跨域:因为浏览器的同源策略,属于不一样域的页面之间不能相互访问各自的页面内容。web
开发中后台项目,咱们首先须要让本地服务run起来,起一个如http://localhost:8000/scg/show
这样的页面,而后,当咱们须要进行网络交互时,一般使用相对域名,如/scg/search.json?pageNo=1
, 假设项目的代理配置以下chrome
那么当请求/scg/search.json?pageNo=1
时,代理转发出去的请求的是http://ottscg.alibaba.net/scg/search.json?pageNo=1, localhost去请求ottscg.alibaba.net中的内容,这时就发生了跨域。json
浏览器经过代理发出CORS请求时,会在头信息之中,增长一个Origin
字段,表示本次请求来自哪一个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否赞成此次请求。若是Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。跨域
若是Origin指定的域名在许可范围内,服务器返回的响应,会多出几个以"Access-Control"开头的头信息字段,为了发送带cookie的跨域请求,咱们首先须要关心的是Access-Control-Allow-Origin
和Access-Control-Allow-Credentials
:浏览器
这个头是容许CORS时,必须返回的头,它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。bash
默认状况下浏览器对跨域请求不会携带 Cookie,但鉴于 Cookie 在身份验证等方面的重要性, CORS 推荐使用额外的响应头字段来容许跨域发送 Cookie。 这是一个可选的头,若发送带cookie的请求,则必须返回这个头,并设置为true,表示服务器容许客户端发送Cookie。 须要注意的是,这个头被设置为true时,Access-Control-Allow-Origin不容许使用*,并且只能指定单一域名,不然浏览器会报以下错误。服务器
综上, 发送cookie的CORS的正确姿式是:cookie
Access-Control-Allow-Origin: Origin;
Access-Control-Allow-Credentials : true
复制代码
The include part tells Chrome that you want to send a CORS request to the server which sends along the cookies properly网络
经过了解CORS原理,咱们知道了不支持CORS的服务端会返回一个正常的HTTP回应,只是因为没有Aceess-control相关的响应头,致使浏览器对响应进行了拦截。利用chrome.webRequest API,对onHeadersReceived进行监听,便可在每次接收到 HTTP(S) 响应标头时,添加须要的header字段,让浏览器觉得这些头信息是服务端返回的,从而绕过CORS限制。app
//Breaking the CORS Limitation
chrome.webRequest.onHeadersReceived.addListener(details=>window.onHeadersReceivedCallback(details), {
urls: ['<all_urls>']
}, ["blocking", "responseHeaders"]);
复制代码
只设置Access-Control-Allow-Origin和Access-Control-Allow-Crendentials两个字段,并不能知足全部的场景。例如,咱们在使用Antd的Upload组件进行上传图片时,Chrome会报以下错误:
Access-Control-Allow-Origin响应头字段能够容许跨域 AJAX, 但对于非简单请求,CORS 机制跨域会首先进行 preflight(一个 OPTIONS 请求,表示这个请求是用来询问的)
具体是指请求方法是简单方法且请求头是简单头的 HTTP 请求。具体地,
Access-Control-Request-Headers 是 preflight 请求中用来标识真正请求将会包含哪些头部字段, 例以下述请求中Access-Control-Request-Headers字段的值是x-requested-with,告知服务器,实际请求将携带这个自定义请求首部字段。服务器据此决定,该实际请求是否被容许,若是容许,服务器应当在对应的Access-Control-Allow-Headers响应头中包含这个字段。 不然即便返回 200 preflight 也会失败。
查看Antd Upload组件的源码,咱们看到,在上传图片时,增长了x-requested-with请求头,由此触发了非简单请求,会在CORS时先进行Option询问
综上,为了处理非简单请求下的CORS,除了Access-Control-Allow-Origin和Access-Control-Allow-Crendentials外,咱们还须要在Header劫持中添加以下配置
Access-Control-Allow-Methods:"*",
Access-Control-Allow-Headers:"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
复制代码