一、简单请求
1.只要同时满足以下两大条件,就属于简单请求
1-1.请求方法是以下三种方法之一
HEAD
GET
POST
1-2.HTTP的头信息不超出以下几种字段:
Accept:-告诉WEB服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
Accept-Language-浏览器申明自己接收的语言 语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等
Content-Language-WEB服务器告诉浏览器自己响应的对象的语言
Content-Type-WEB服务器告诉浏览器自己响应的对象的类型。
(text/html是html格式的正文)
(text/plain是无格式正文)
(application/json是json字符串)
(multipart/form-data是基于post方法来传递数据的)
(application/x-www-form-urlencoded是form表单形式的数据)
2.当浏览器发现发现的ajax请求是简单请求时,会在请求头中携带一个字段:Origin
Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。
二、特殊请求
1.不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT
2.特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
一个“预检”请求的样板:
OPTIONS /cors HTTP/1.1
Origin: http://manage.leyou.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.leyou.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
与简单请求相比,除了Origin以外,多了两个头:
Access-Control-Request-Method:接下来会用到的请求方式,比如PUT
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://manage.leyou.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 1728000
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
除了Access-Control-Allow-Origin和Access-Control-Allow-Credentials以外,这里又额外多出3个头:
Access-Control-Allow-Methods:允许访问的方式
Access-Control-Allow-Headers:允许携带的头
Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了
如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的了。