Zhi-Ling

You can do Everything you want

0%

CORS

Brief Introcors introduction and ways to solve it

  • 简单请求
  • 非简单请求
  • JSONP

跨域含义

http://www.google.com:80
协议、域名、端口三者其中之一不一样进行请求都属于跨域请求

简单请求和非简单请求

简单请求

条件

1、请求方法为:HEAD、GET、POST
2、HTTP 头信息不超过字段:Accet、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

请求方式

在头信息中增加一个 origin 字段,用来说明本次请求来自哪个源,服务器决定是否同意该请求

GET /cors? HTTP/1.1
Host: localhost:2333
Connection: keep-alive
Origin: http://localhost:2332
User-Agent: Mozilla/5.0 (WindowsNT10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98Safari/537.36
Accept: /

如果 origin 指定的源不在允许范围内,会返回一个正常的 HTTP 回应。如果头信息中没有包含 Access-Control-Allow-Origin 就会抛出错误

Access-Control-Allow-Origin: http://localhost:2332 (必填,接收哪些域名请求)
Access-Control-Allow-Credentials: true (可选,是否可以发送 Cookie)
Access-Control-Expose-Headers: FooBar (可选,除了 6 种服务器基本字段,其他可指定)
Content-Type: text/html; charset=utf-8

携带 Cookie

服务端与客户端都需要设置
服务端:Access-Control-Allow-Origin:http://xxx:${port}
Access-Control-Allow-Credentials: true
客户端:withCredentials = true

非简单请求

预检请求

一般对于请求方式为 PUT、DELETE 或者是 ContentType:application/json 等特殊服务器请求;
非简单请求的 CORS 会在正式通信之前做一次预检请求,来判断当前域名是否在服务器的许可范围名单之内,以及可以使用哪些 HTTP 方法和头信息字段,肯定回复后浏览器发出正式的 XMLHttpRequest 请求。

var url = ‘http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open(‘PUT’, url, true);
xhr.setRequestHeader(‘X-Custom-Header’, ‘value’);
xhr.send();

以上是一个非简单请求,请求方式为 PUT,发送一个自定义头信息 X-Custom-Header,浏览器会发送一个 “预检” 请求

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0…

预检的请求方法为 OPTIONS,表示用来询问。检查完 Origin、 Access-Control-Request-Method 和 Access-Control-Request-Headers 字段以后,确认允许跨源请求。下面是预检请求的响应头

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com (* 表示所有任意跨域请求)
Access-Control-Allow-Methods: GET, POST, PUT (必须,表明服务器支持的请求方式)
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

如果拒绝了预检请求,返回的头信息中没有任何包括 CORS 相关信息

OPTIONS http://api.bob.com HTTP/1.1
Status: 200
Access-Control-Allow-Origin: https://notyourdomain.com
Access-Control-Allow-Method: POST

与 JOSNP 比较

JSONP 是通过 script、img、iframe 等不受同源策略限制的标签携带 src 进行跨域请求,并接受返回函数进行回调。因而只支持 GET 请求。
优点:JSONP 支持低版本浏览器。
CORS 更强大,支持所有的 HTTP 请求方式

Welcome to my other publishing channels