美文网首页
HTTP学习笔记-CORS

HTTP学习笔记-CORS

作者: Patrick浩 | 来源:发表于2018-01-01 09:21 被阅读0次
    Http跨域.png

    1. 简介

    CORS(Cross Origin Resource Shared)是一种对服务端请求资源时的权限限制,出于安全原因考虑,浏览器在限制在通过脚本获取资源的时候只能获取同源的数据资源,如果要获取非同源的数据资源,则需要请求时增加CORS头信息。
    非同源的数据资源是指需要访问的数据资源和当前的站点具有不同域名(domain),端口(port),协议(protocol)等。

    2. 产生跨域条件

    并不是所有的请求都会需要产生跨域。
    首先,跨域是浏览器为了安全的一种限制,因此部分浏览器是可以关闭跨域安全限制的。
    其次,跨域是利用脚本请求数据资源时才会带来的限制,于是对于非脚本请求,例如通过浏览器直接访问一个数据资源是不会产生跨域的。
    总的来说,通常以下几种情况会产生跨域:

    1. 使用XMLHttpRequest或者Fetch API请求资源
    2. css中使用@font-face获取web字体资源
    3. WebGL texture
    4. img或者video使用了Canvas的drawImage

    3. 跨域请求和响应

    通过跨域请求时所携带的请求信息不同,服务端需要有不同的响应,这里所说携带的请求信息主要指请求的头信息中携带的信息

    3.1 简单请求

    简单请求是指请求的时候不会优先发送OPTIONS请求的跨域请求

    3.1.1 条件

    简单请求有5个限制条件

    1. 请求的Method只能是GETPOSTHEAD请求
    2. 请求的Headers只能包含AcceptAccept-LanguageContent-LanguageContent-TypeLast-Event-IDDPRSave-DataViewport-WidthWidth
    3. 请求的Headers中的Content-Type只能是application/x-www-form-urlencodedmultipart/form-datatext/plain
    4. XMLHttpRequest中没有使用xhr.upload对象
    5. 没有使用ReadableStream对象
    3.1.2 过程

    对于简单请求,浏览器会在请求的时候头信息中添加Origin,等待服务端返回的ResponseHeaders中携带的Access-Control-Allow-Origin信息,来判断是否可以访问资源
    参考MDN中的请求过程图

    simple_req.png

    3.2 Preflight请求

    Preflight请求在跨域请求的时候会优先发送OPTIONS请求到服务器,根据响应来当前的请求是否是安全的,是否可以继续请求资源数据

    3.2.1 条件

    所有非简单请求都会发送Preflight请求

    3.2.2 过程

    对于Preflight请求,首先发送OPTIONS请求,并在头信息中包含OriginAccess-Control-Request-HeaderAccess-Control-Request-Method信息,服务端会根据设置在响应头信息中增加Access-Control-Allow-OriginAccess-Control-Allow-HeadersAccess-Control-Allow-Methods,来告知浏览器当前请求是否支持,如果不支持,则停止请求;如果支持,则浏览器会再次发起相应Method的请求,并携带Origin信息,服务端会再次在响应头中返回Access-Control-Allow-Origin信息,并返回数据信息。
    同样在MDN上有一个很清楚的请求过程的图解

    prelight.png

    3.3 withCredentials请求

    3.3.1 作用

    特别的通过XmlHttpRequest或者Fetch API进行跨域请求的时候,通常是不会携带Cookie信息或者HttpAuthentication信息的,但是如果不携带Cookie信息,例如:如果使用了服务端Session,因为不携带Cookie信息,那么就没办法获取到对应的Session。于是需要增加withCredentials设置

    3.3.2 过程

    XMLHttpRequest为例,在请求的时候需要设置xhr.withCredentials=true,之后在客户端发起请求的时候会传递Cookie信息,服务端在接受到信息以后会在响应头返回Access-Control-Allow-WithCredentialsSet-Cookie信息,浏览器通过返回的信息判断请求是否有效
    也可以参见MDN的请求过程图解

    cred-req.png
    这里需要注意的是,如果服务端设置了Access-Control-Allow-WithCredentials: true,那么我们在服务端配置的Access-Control-Allow-Origin不能使用*的通配符

    4. 总结

    总的来说,跨域是要特定情况下才会产生的,最常见的就是使用AJAX来请求数据资源的时候产生跨域;跨域请求会根据头信息不同,浏览器会判断是否优先发送OPTIONS请求;对于需要传递Cookie的请求,我们需要设置withCredentials

    5. 参考

    MDN CORS
    MDN Server-side CORS

    相关文章

      网友评论

          本文标题:HTTP学习笔记-CORS

          本文链接:https://www.haomeiwen.com/subject/zsbrgxtx.html