跨域请求

两种结果

  • 一种 request 会收不到 response,因为 response 被浏览器拦截了,内容不告诉你
  • 另一种请求会根本发不出去,因为浏览器不允许发出那样的 request

simple 请求跨域

条件

  1. 请求方法是以下3种方法

    • HEAD
    • POST
    • GET
  2. 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 请求跨域

  1. 不是 GET,HEAD,POST 请求;比如是 PUT 请求
  2. 包含一些非 CORS 协议默许的 headers,比如Authorization,X-Request-With 或者一些自定义的headers。
  3. Content-Type 不是默许的那 3 种
    注释:
  4. 浏览器发送 preflight request(那个 OPTIONS 请求[2])
  5. 浏览器收到 preflight response(也就是刚刚那个 request 的返回)
  6. 浏览器根据 preflight response 中的 Access-Control-Allow-Origin, Access-Control-Allow-Headers以及其他Access-Control-*类的headers 中的 value 来判断网页程序真正要发出的 request 是否符合要求
  7. 如果这个 request 符合要求,request 被发出,网页程序可以收到正常的 response(如果不出网络通讯上的意外);如果这个 request 被判定为不符合要求,这个 request 干脆就不会被发出。
    以上这些步骤都是同步的,preflight request 和 真正的request 是有先后顺序的

    跨域时带身信息(Access-Control-Allow-Credentials)

    服务器允许客户端表明身份

    1. 将Access-Control-Allow-Credentials设置为true

    三种默认的表明身份的方式是:

    1. Cookie: 在 request 的 header 中 Cookie 这一项
    2. Authorization: 在 request 的 header 中 Authorization 这一项
    3. 使用了 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...


这有一个错误
28 声望1 粉丝

!盗版前端工程师