美文网首页网络
跨域请求CORS

跨域请求CORS

作者: qishuai | 来源:发表于2022-06-09 17:48 被阅读0次

预备知识:

  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请求,在不进行跨域请求配置的情况下。

跨域请求的解决方案:

  • 简单请求

    • 请求method只能是GET/POST/HEAD
    • 仅能使用CORS安全的Header: Accept、Accept-Language、Content-Language、Content-Type
    • Content-Tytpe只能是如下的一种:text/plain、multipart/form-data、applicaton/x-www-form-urlencoded
    • 请求中必须携带Origin头部,服务端通过响应Access-Control-Allow-Origin头部来只是浏览器该如何处理该请求(如果Access-Control-Allow-Origin为Origin的值或者为*时,浏览器才允许渲染请求结果)
  • 复杂请求

请求示例:

  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';
这种也是不行的

相关文章

  • 用express实现CORS跨域

    跨域请求头 cors express 跨域请求

  • CORS跨域请求,怎么将Cookie传给后端

    CORS跨域请求,怎么将Cookie传给后端 后端 增加代码: //CORS跨域 允许Authorization ...

  • SpringBoot2.x整合CORS解决跨域问题

    跨域问题系列文章 1. 同源策略与CORS(跨域请求的起源)2. SpringBoot2.x整合CORS解决跨域问...

  • AJAX 跨域请求常用两种处理方法

    AJAX 跨域请求常用两种处理方法 -- 第一、 使用 跨域资源共享(CORS) CORS(Cross-Origi...

  • JavaScript - GET/POST及跨域方法

    xhr 原生方法请求 window fetch 方法 关于跨域 利用JSONP实现跨域调用 使用 CORS(跨域资...

  • django跨域配置

    前言——跨域请求 前端对Cross-Origin Resource Sharing 问题(CORS,中文又称'跨域...

  • Spring Boot跨域

    前后端分离时候势必会遇到Ajax跨域请求。 1. 关于跨域 参考跨域资源共享 CORS 详解 CORS是一个W3C...

  • 跨域CORS

    CORS全称是跨域资源共享(Cross-Origin Resource Sharing),用来解决AJAX跨域请求...

  • AJAX入门

    处理跨域的主要方法 JSONP CORS本文主要讨论CORS解决AJAX因为浏览器同源策略不能跨域请求数据的问题。...

  • 跨域请求

    前言:对跨域请求、CORS和CSRF做名词解释,没有深入展开。想深入了解跨域看下面的两篇文章。 跨域请求 什么是跨...

网友评论

    本文标题:跨域请求CORS

    本文链接:https://www.haomeiwen.com/subject/geymmrtx.html