解决跨域请求之CORS

当发出去的请求是XHRHttpRequest请求时(type:xhr)则是跨域请求,浏览器会出于安全考虑。会对该类请求进行限制。

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)符合该标准,允许浏览器向跨源服务器,发出XHRHttpRequest请求。

简介:

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。服务器返回的响应中需要回应浏览器,也需要附加一些响应头信息。

浏览器会将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

简单请求:

1、请求方法为GET、POST、POST。 

2、请求Header中无用户自定义头。

3、请求Content-type为,text/plain、multipart/form-data、application/x-www-form-urlencoded、三种类型之一。

非简单请求:

1、请求方法为PUT、DELETE。

2、请求Header中带有用户自定义头。

3、发送JSON格式的ajax请求。 请求Content-type=application/json。

简单跨域请求流程:

当浏览器发送跨域请求,会自动在请求头中增加Orgion字段。Origion=调用方的域名(协议 + 域名 + 端口)。服务器可根据Origion这个值,决定是否同意这次请求。当请求返回时,浏览器也会去检查响应头中是否包含允许跨域的字段信息(Access-Control-Allow-Origin-允许的调用域、Access-Control-Allow-Method-允许跨域调用的方法)。如果存在,会判断允许的调用域中是否包含该次请求的域。如果回应的头信息没有包含Access-Control-Allow-Origin字段。或者Access-Control-Allow-Origin字段允许调用域不包含发起请求的域,浏览器会认为跨域调用失败。但HTTP回应的状态码有可能还是200。

简单请求CORS字段:

1、Access-Control-Allow-Origin:"http://www.zjhApiTest02.com" ("*"  标识允许所有域调用。)

2、Access-Control-Allow-Methods:GET 允许跨域请求的调用方式("*" 标识允许所有调用方式)

3、Access-Control-Allow-Credentials 该字段可选。值是布尔值,表示是否允许发送Cookie (服务器不允许发送Cookie,删除该字段即可)

非简单请求流程:

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)又称"options请求"。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有浏览器在响应头中获得答复,浏览器第二次才会发出正式的XMLHttpRequest请求,否则就报错跨域请求失败。

"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源,字段:Access-Control-Allow-Headers 指定浏览器CORS请求会额外发送的头信息字段  字段Access-Control-Request-Method 该字段是必须的,用来列出浏览器的CORS请求HTTP方法。服务器收到"预检"请求以后,检查OriginAccess-Control-Request-MethodAccess-Control-Request-Headers字段以后,确认是否允许跨源请求。然后服务端返回的响应头中增加Access-Control-Allow-Origin字段。该字段为"*" 标识允许任意域跨域访问。

当没有任何CORS相关的头信息字段。或者响应中的Access-Control-Allow-Origin字段不包含当前请求域,浏览器就会认定,服务器不同意预检请求跨域访问会触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。控制台会打印出报错信息。

当通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

非简单请求CORS字段:

1、Access-Control-Allow-Methods:必要字段,多个值是用逗号分隔的字符串,表明服务器支持的所有跨域请求的方法。

注意:返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

2、Access-Control-Allow-Headers:表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

3、Access-Control-Allow-Credentials:是否允许携带Cookie与简单请求一样。

4、Access-Control-Max-Age:字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。

总结:

1、简单跨域请求,只会发起一次请求,请求会带有CORS的头信息字段。非简单请求:第一次发送options预检请求,预检通过,之后会再发起一次真实跨域请求,如果响应头中设置Access-Control-Max-Age字段,期间跨域访问不再会发Option请求。

2、简单请求和非简单请求跨域访问时,浏览器都会在请求头中增加字段Origin。

该篇是参考阮老师的写的。阮老师传送门

猜你喜欢

转载自blog.csdn.net/qq360694660/article/details/81459240