跨域请求
两种结果
- 一种 request 会收不到 response,因为 response 被浏览器拦截了,内容不告诉你
- 另一种请求会根本发不出去,因为浏览器不允许发出那样的 request
simple 请求跨域
条件
请求方法是以下3种方法
- HEAD
- POST
- GET
HTTP的头信息不超出以下几种字段
- 只能有浏览器默认添加的 headers,以及一些 CORS 协议中默许的 headers 比如 Accept 等,更多被允许的 headers,可以看这里
- Accept
- Accept-Language
- Content-Language
- Lase-Event-ID
- Content-Type: 只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
注:
一旦一个 request 是 simple request,那么,尽管这个请求是跨域的,它也会被浏览器直接放行。但是,在 response 返回的时候,浏览器并不会把 response 直接交给你,而是去检查这个 response 的 headers 中有没有 Access-Control-Allow-Origin,以及这个 header 的 value 包含 request 发出的地址(也就是“域”)。如果两个条件都满足, response 会被返回给发出请求的程序;如果没有这个 header 或者 value 不对, response 就会被拦截下来,因为在浏览器看来,这个 response 不属于你(因为服务器没有明确允许你这个“域”来请求它)。如果你使用的是 chrome 浏览器,在 response 被拦截下来的时候,console 中会显示一个错误。
preflight 请求跨域
- 不是 GET,HEAD,POST 请求;比如是 PUT 请求
- 包含一些非 CORS 协议默许的 headers,比如Authorization,X-Request-With 或者一些自定义的headers。
- Content-Type 不是默许的那 3 种
注释: - 浏览器发送 preflight request(那个 OPTIONS 请求[2])
- 浏览器收到 preflight response(也就是刚刚那个 request 的返回)
- 浏览器根据 preflight response 中的 Access-Control-Allow-Origin, Access-Control-Allow-Headers以及其他Access-Control-*类的headers 中的 value 来判断网页程序真正要发出的 request 是否符合要求
如果这个 request 符合要求,request 被发出,网页程序可以收到正常的 response(如果不出网络通讯上的意外);如果这个 request 被判定为不符合要求,这个 request 干脆就不会被发出。
以上这些步骤都是同步的,preflight request 和 真正的request 是有先后顺序的跨域时带身信息(Access-Control-Allow-Credentials)
服务器允许客户端表明身份
- 将Access-Control-Allow-Credentials设置为true
三种默认的表明身份的方式是:
- Cookie: 在 request 的 header 中 Cookie 这一项
- Authorization: 在 request 的 header 中 Authorization 这一项
- 使用了 TLS 证书
让客户端浏览器自动带上身份信息
在进行跨域请求时,浏览器默认不会带上 cookie(这个 cookie 是针对目标域的 cookie,而不是原来“域”的 cookie),但是如果在构建 xhr 对象时,把XMLHttpRequest.withCredentials这个属性设为 true,浏览器会自动帮你带上目标域的cookie
参考文档
https://www.jianshu.com/p/d21...
https://developer.mozilla.org...
https://blog.csdn.net/Daijian...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。