跨域问题的解决方案

0.722字数 477阅读 369
  • 推荐文章

1.Nginx配置跨域请求 Access-Control-Allow-Origin *

2.跨域资源共享 CORS 详解

3. 浏览器同源政策及其规避方法

只要是 AJAX 请求,都会有同源策略的问题,都需要解决跨域的问题。
跨域的问题有两种解决方式。
第一种、需要从两方面解决,一方面是 apache 或者 nginx 服务器,
另一方面是从 后端代码 上解决
第二种、解决方式是使用jsonp 格式

php 代码处理

<?php
header('Access-Control-Allow-Origin:http://test'); // 单个域名处理
// header('Access-Control-Allow-Origin:*'); // 允许所有域名
echo '---跨域请求成功';

目前还没有找到后端怎么在一个 header() 函数上配置多个域名的方法,只知道一个一个的配置,尝试了数组和字符串的方式都不行。如果哪位朋友知道怎么处理,可以告知。谢谢。注意,冒号后面的域名参数不能添加引号

nginx 配置

1. $ /etc/nginx/site-available/homestead.test   在 location 中添加以下参数
location / {  
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
    }
} 
  • 重启 nginx sudo service nginx reload
    参数详细解释,可以参考第一篇文章。

apache 没有找到很好的资料,不过以下方式应该是可以解决的。我没有测试

可以配置具体请求的Header,或者在apache配置文件里面进行统一配置(所以使用set 而不是 add);即在<VirtualHost>节点或者<Directory>节点下添加如下代码:

Header set Access-Control-Allow-Origin "http://homestead.test"
或者
Header set Access-Control-Allow-Origin "*"

测试

<html>
<head>
    <script type="text/javascript" src="http://hemin.cn/jq/js/jquery.min.js"></script>
    <title>跨域测试</title>
</head>
<body>
<h1>跨域测试</h1>
<script type="text/javascript">
    var url = 'http://homestead.test/test.php';
    $.ajax({
        url: url,
        cache: false,
        success: function (html) {
            $("h1").append(html);
        },
        error: function () {
            alert('请求失败');
        }
    });
</script>
</body>
</html>

这时候,前端可以无障碍的请求 http://homestead.test 站点上的任何数据了
单数需要注意,如果你配置的是 http 只能通过 http 请求,而不能使用 https 这是同源策略中的一个要点。


jsonp 解决方案

  • index.html
<html>
<head>
    <script type="text/javascript" src="http://hemin.cn/jq/js/jquery.min.js"></script>
    <title>跨域测试</title>
</head>
<body>
<h1>跨域测试</h1>

<script type="text/javascript">
    // var url = 'http://homestead.test/test.php';
    var url = 'http://test/test.php'; // 很多资料说需要添加参数  ?callback=jsonpCallback 其实不需要,在请求的时候会自动带上

    $.ajax({
        url: url,
        type: 'GET',
        cache: false,
        dataType: 'jsonp',
        jsonpCallback: 'callback', // callback 这个值必须是后端返回的函数名
        success: function (html) {
            console.log(html);
        },
        error: function (res) {
            alert('请求失败');
        }

    });

</script>
</body>
</html>
  • test/test.php
<?php
// header('Content-Type', 'text/javascript; charset=utf-8');   // 这个可加可不加
//服务端返回JSON数据
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
$result=json_encode($arr);
//动态执行回调函数
$callback=$_GET['callback'];
echo   $callback."($result)";    // $callback 必须与前端 `jsonpCallback` 的值一致
ajax 请求的键和值都是jsonpCallback 的值
test.php 返回的数据

在前端 console.log 打印的请求数据
  • jsonp 跨域总结
    1、ajax 请求要添加 dataType: 'jsonp', jsonpCallback: 'callback', 参数
    2、后端代码返回的数据格式必须是 $callback=$_GET['callback']; echo $callback."($result)"; 格式

推荐阅读更多精彩内容