跨域

网上找到的一遍非常好的跨域相关的知识描述,加上之前也做了一次nginx的代理docker,故将相关的记录一下。

资源

非常好的一遍文章。

https://www.toutiao.com/a6781216693029962243/

正文

response Headers信息也很正常,这说明在跨域的情况下请求依然可以到达服务器,并且服务器能够正常响应,但是由于浏览器的同源策略并没有把返回的数据给到页面。

step1

Access-Control-Allow-Origin': '*'   # 表示接受任意域名的请求

step2

服务器有时依然需要鉴权,需要传递cookie。但是cookie会遵守同源策略!

Access-Control-Allow-Credentials: true 

页面的xhr对象也要设置:

var xhr = new XMLHttpRequest();

xhr.withCredentials=true;

step3

允许客户端携带的header头。

Access-Control-Allow-Headers: 'token';

step4

简单请求与非简单请求

简单请求定义

  • 请求方法是必须是HEAD/GET/POST三种方法之一;
  • HTTP的头信息不超出这几种字段:Accept/Accept-Language/Content-Language/Content-Language/Last-Event-ID/Content-Type,Content-Type只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain。

非简单请求的CORS请求会在正式通信之前增加一次HTTP查询请求,称为预检请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。预检请求用的请求方法是OPTIONS,表示这个请求是用来询问的。

非简单请求,会发送两次请求。所以,OPTIONS请求,直接拦截掉,避免到达具体的业务层。

允许的提交的方式。

Access-Control-Allow-Methods: 'GET'

nginx配置

location /loc/ {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, DELETE, PUT, 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,  Access-Control-Expose-Headers, Token, Authorization';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
    add_header 'Access-Control-Allow-Origin' '*' always;
    proxy_pass http://10.20.24.223:8005/;
}