跨域问题

产生跨域的原因

  • 浏览器的限制
  • 跨域
  • XHR(XMLHttpRequest)请求

解决思路

  • JSONP
  • nginx 代理
  • 浏览器禁止检查跨域

浏览器禁止检查跨域(以 chrome 为例)

  1. 彻底关闭 chrome
  2. 使用命令行启动
  • mac
open -a "Google Chrome" --args --disable-web-security --user-data-dir
  • windows
/PATH_TO/chrome.exe --args --disable-web-security --user-data-dir
# 也可以使用快捷方式去设置
  • safari
open -a '/Applications/Safari.app' --args --disable-web-security --user-data-dir 

JSONP解决跨域

什么JSONP

JSONP(JSON with Padding)是JSON的一种“使用模式”,通过这种模式可以实现数据的跨域获取

JSONP解决跨域

同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码

JSONP 弊端

  • 服务器需要改动代码
  • 只支持 GET
  • 发送的不是 XHR 请求

nginx 解决跨域

location / {
    add_header Access-Control-Allow-Origin *.abc.com;
    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';
}

说明:

  1. Methods,Headers 根据业务需求做改动
  2. 开发环境可以使用*号代替
  3. Access-Control-Allow-Origin选项如果指定具体的域名,要带上协议,eg: https://test.abc.com

测试跨域问题代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>CORS跨域</title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<div style="text-align:center;margin-top: 100px;font-size: 60px;color: brown;cursor: pointer;">
    <span onclick="sendAjaxReq()">发送Ajax请求</span>
</div>
<script type="text/javascript">
    function sendAjaxReq() {
        $.ajax({
            type: "GET",
            // contentType: "application/json",
            url: "http://www.baidu.com/v3",
            headers: {
                "requestid": "123456789",
            },
            success: function (message) {
                console.log("成功!" + message);
            },
            error: function (a, b, c) {
                console.log("失败!" + a.statusText);
            }
        });
    }
</script>
</body>
</html>