本文为前端学习http的一部分,请结合github上的实例进行阅读能有更深的体会,Enjoy your time!
CORS
背景:为了提高安全性,浏览器添加了同源策略限制跨域访问;但与此同时降低了开发的灵活性。为此,浏览器提供了折中方法,只要遵循CORS协议,跨域也可访问。
定义:CORS全称:cross-origin resource sharing,跨域资源共享。实现方式是服务端添加若干请求头(以下详解)。
此方法有兼容性的限制,主要限制是IE11才支持CORS。
preflighted requests
在跨域的情况下,请求被分为两种simple requests和preflighted requests,它们(的条件)是相互排斥的。
满足以下任一条件为preflighted requests:
- 请求的方法为:PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
- 有超过以下内容(又被称为"CORS-safelisted request-header")的请求头:
Accept, Accept-Language, Content-language, Last-Event-ID, DPR, Downlink, Save-Data, Viewport-Width, Width, Content-Type(值必须为以下3个:application/x-www-form-urlencode, multipart/form-data, text/plain)
比如说:请求头含有Content-Type: application/xml。虽然是Content-Type,但它的值不是3个可选值之一。所以这个请求为preflighted requests。
特点:在发送preflighted requests真正请求之前,会发送OPTIONS请求去验证。
options
定义:在跨域的情况下,如果请求为preflighted request,则在请求前,浏览器会自动先发送options请求,去探测是否安全,来决定是否要发送真正的请求。
例子:
var myRequest = new Request('http://0.0.0.0:41230/api', {
credentials: 'include',
method: 'PUT',
headers: {
'Content-Type': 'application/xml'
}
})
Access-Control-Allow-Origin
定义: 服务端response headers添加这个字段,表示可以允许跨域访问。值为允许访问的来源域,也既是request的origin,比如http://bar.com,或*(表示任意来源域都可以访问)。如果使用了credentials字段,则不能用*。
例子:
app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "*");
// 由于有credentials,Access-Control-Allow-Origin的值必须为某个域名
res.header("Access-Control-Allow-Origin", "http://0.0.0.0:41239");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
})
Access-Control-Allow-Methods
定义:在跨域的情况下,如果请求为preflighted request,则必须添加这个字段,值为允许的请求方式。
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, PUT, DELETE, TRACE, PATCH')
next();
})
Access-Control-Allow-Headers
定义:在跨域的情况下,如果含有特殊请求头,使得请求变为preflighted request,则必须添加这个字段。值为特殊请求头。
//客户端
var myRequest = new Request('http://0.0.0.0:41230/api', {
headers: {
'Content-Type': 'application/json', //常规头部信息,但是值特殊,也触发了preflighted request
'X-PINGOTHER': 'pingpong' //特殊头部信息
}
})
//服务端
app.use(function (req, res, next) {
res.setHeader('Access-Control-Request-Headers', 'X-PINGOTHER', 'Content-Type')
next();
})
Access-Control-Allow-Credentials
定义:在跨域的情况下发送HTTP cookies或者HTTP Authentication information,需要client和server共同设置credentials字段才能发送成功。
// 服务端
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Credentials', true)
next();
})
//客户端
// ajax withCredentials: true
// fetch credentials: 'include'
参考资料
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.ruanyifeng.com/blog/2016/04/cors.html