CORS简单请求和非简单请求

2,445 阅读2分钟

简单请求:

同时满足两大条件的请求是简单请求

(1) 请求方法是以下三种方法之一:

HEAD

GET

POST

(2)HTTP的头信息不超出以下几种字段:

Accept:指定返回类型,: text/plain(纯文本类型), text/html(html类型)

Accept-Language 指定返回语言

Content-Language 指定内容语言

Last-Event-ID

Content-Type:只限于三个值

application/x-www-form-urlencoded:对发送内容进行编码

multipart/form-data:上传的表单内包含文件

text/plain:发送内容为纯文本格式

简单请求head里包含origin字段. origin组成部分:协议+域名+端口号

Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

服务器收到请求后,检查Origin是否在自己的许可范围之内,若不在,返回一个正常的Http响应。但响应头内不包含Access-Control-Allow-Origin。若在许可范围之内,响应头如下:

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

非简单请求

以下代码是一个非简单请求:(因为他的header里面包含X-Custom-Header

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

当浏览器发现这是一个非简单请求,不需要用户操作,浏览器自动发送一个OPTION请求(也叫做预检操作)其中核心内容有两部分,Access-Control-Request-Method表示后面的请求需要用到这个方法,Access-Control-Request-Headers表示后面的请求头内会有该内容。

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...

服务器收到预检请求后,检查这些特殊的请求方法和头自己能否接受,并且响应头包含如下信息:

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
Content-Type: text/plain

返回信息中最关键的是指定了服务器能够接受的请求方法和Header内的内容。如果服务器支持预检中的Header和Methods,那么接下来就可以正常发送信息。

与普通和请求响应的区别是,CORS请求头中会多出 Origin,而响应头中会多出 Access-Control-Allow-Origin

比JsonP强在哪?JsonP只支持Get请求