网络

跨域请求CORS

2022-06-09  本文已影响0人  qishuai

预备知识:

  1. 只有浏览器才会有跨域请求限制,也就是如果是服务器之间直接发起http请求不会存在该限制。
  2. CORS是在不满足同源策略的情况下,才有可能引起跨域请求限制。
  3. 同源策略校验包括protocol + host/domain + port(80/443会省略),只有三者完全相同是,才满足同源策略。
  4. <script><img><iframe><link><video><audio>带有src属性,浏览器允许跨域请求
  5. 表单提交、重定向允许跨域写操作(此时可能引起CSRF,可以通过埋token的方式避免)
  6. 浏览器不支持跨站点访问Cookie、LocalStorage、IndexDB
  7. 浏览器不支持跨站点访问DOM
  8. 浏览器不支持跨站点的AJAX请求,在不进行跨域请求配置的情况下。

跨域请求的解决方案:

请求示例:

  1. 创建html文件,内部含有Ajax请求(http://127.0.0.1:8081和http://127.0.0.1:8082不满足同源策略)
<html>
<body>
    <p>跨域请求测试</p>
    <p id="resp"></p>
    <script>
        var invocation = new XMLHttpRequest();
        var url = "http://127.0.0.1:8082";

        function handler() {
            if (invocation.readyState == 4) {
                if (invocation.status==200) {
                    console.log(invocation.responseText);
                    document.getElementById('resp').innerHTML=invocation.responseText;
                }
            }
        }

        function callOtherDomain() {
            if (invocation) {
                invocation.open('GET', url, true);
                invocation.onreadystatechange = handler;
                invocation.send();
            }
        }

        callOtherDomain();
    </script>
</body>
</html>%
```html

2. 配置nginx server
server {
    listen      8081;
    server_name localhost;
    charset     utf-8;

    location / {
        # 这个地方需要修改成你上面保存的cors.html的目录
        root /path-to-directory;
        index cors.html cors.htm;
    }
}

server {
    listen      8082;
    server_name localhost;
    charset     utf-8;

    location / {
        return 200 'hello world';
    }
}

保存,执行nginx -s reload

  1. 打开浏览器,访问http://127.0.0.1:8081。你将会发现http://127.0.0.1:8082的Ajax请求失败了,浏览器提示CORS error(MissingAllowOriginHeader) 。
    但是通过抓包可以看到,nginx其实将相应('hello world')返回给浏览器了,但是由于不满足CORS policy,相应被浏览器隐藏了。抓包截图:


    image.png

3.1 修改8082站点的配置,以允许来自8081的跨站请求

    server {
        listen      8082;
        server_name localhost;
        charset     utf-8;

        location / {
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            return 200 'hello world';
        }
    }

再次刷新浏览器,可以发现请求正常返回了
因为Response header中返回了Access-Control-Allow-Origin: http://127.0.0.1:8081

4. 更多的跨域请求响应Header

image.png

5. 常见错误

5.1 MultipleAllowOriginValues

Access to XMLHttpRequest at 'http://127.0.0.1:8082/' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://127.0.0.1:8081, http://127.0.0.1:8083', but only one is allowed.

原因:response header中返回了多个AccessControlAllowOrigin值(可以是相同的,也可以是不同的)。例如如下的服务端返回:

    server {
        listen      8082;
        server_name localhost;
        charset     utf-8;

        location / {
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            return 200 'hello world';
        }
    }

Access-Control-Allow-Origin只能返回一个源

add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
add_header Access-Control-Allow-Origin 'http://127.0.0.1:8083';
这种不同的源也是不行的,即使相同的源也是不行的。
add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081,http://127.0.0.1:8083';
这种也是不行的

上一篇 下一篇

猜你喜欢

热点阅读