为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

非同源限制

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

跨源资源共享 (CORS)

CORS 是跨域资源共享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

跨源资源共享(CORS)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的”预检”请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。

CROS示意图:

cros示意图

如上图所示:CROS请求时首先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。

Nginx跨域配置

server {
    listen  80 default_server;
    server_name _;  
              
    location / {

        # 添加跨域header
        add_header Access-Control-Allow-Origin $http_origin; # 允许跨域的域名
        add_header Access-Control-Allow-Methods $http_access_control_request_method; # 允许跨域的方法
        add_header Access-Control-Allow-Credentials true; # 可以使用凭据 包括 cookie、authorization headers 、 TLS 证书
        add_header Access-Control-Allow-Headers $http_access_control_request_headers; # 允许跨域携带的header

        
        # 响应跨域预检
        if ($request_method = 'OPTIONS') {

            # 设置跨域预检缓存
            add_header Access-Control-Max-Age 1728000;
            return 204;
        }         
    }
 
}

千万不能同时设置Credentials=true且Origin=,浏览器会报错: has been blocked by CORS policy: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘’ when the request’s credentials mode is ‘include’. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute

(完)

文章参考:懒的去其Demi跨源资源共享(CORS)