CORS

作者: 一蓑烟雨任平生_cui | 来源:发表于2020-06-09 18:16 被阅读0次

    由于浏览器同源策略(协议、域名、端口)的限制,当浏览器向跨源服务器发起请求时,会出现跨域。

    解决跨域的方式有多种,比如jsonp、CORS、Iframe、nginx正、反向代理等。

    本文着重介绍CORS。

    介绍:

    CORS全称是跨域资源共享。需要浏览器和服务器的同时支持。目前所有浏览器都支持,IE需要10以上。

    整个通信过程都是浏览器自动完成的,前端开发者不需要做任何设置,关键在于服务器端。

    当浏览器发现请求跨域时,就会自动添加一些头部信息,有时会多出一次请求(预检请求),对用户是无感知的。

    请求方式

    CORS的请求方式有两种,简单请求和非简单请求(需要预检请求)。

    1、简单请求

    条件:

    同时符合以下两个条件为简单请求:

    1. 请求方式
      • GET
      • POST
      • HEAD(只获取报文首部)
    2. 除了浏览器自己在Http头上加的信息(如Host、Connection、User-Agent等)之外,开发者只能加下列字段:
      • Accept
      • Accept-Language
      • Content-Language
      • DPR
      • Downlink
      • Save-Data
      • Viewport-Width
      • Width
      • Content-Type 值仅限于三个之一(text/plain、multipart/form-data、application/x-www-form-urlencoded)
    流程:

    当浏览器发现是跨源请求时,会自动在头部增加Origin字段,用来说明请求源(协议、域名、端口),服务器会根据该字段值决定是否允许请求。

    简单请求request头部信息

    如果Origin不在服务器的允许的范围,服务器会返回正常的HTTP响应,但响应头中如果不包含Access-Control-Allow-Origin字段,浏览器发现没有该字段便会抛出错误。需要注意的是,这种错误无法通过状态码识别,因为HTTP响应的状态码有可能是200。

    如果Origin在允许的范围内,服务器会在响应头中多出以下字段:

    1. Access-Control-Allow-Origin:必选。值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
    2. Access-Control-Allow-Credentials,可选。值为boolean, 表示是否允许浏览器发送cookie,如果不需要,不设置该字段即可。如果要发送,还需要服务器同意,响应头设置Access-Control-Allow-Credentials: true,同时ajax对象设置该属性ajax.withCredentials = false
    3. Access-Control-Expose-Headers,可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
    简单请求response头信息

    注意: 如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。

    非简单请求(需预检请求)

    所谓非简单请求是对服务器有特殊要求的请求,比如:

    请求方法是:

    1. PUT 传输文件
    2. DELETE 删除文件
    3. CONNECT 要求用隧道协议连接代理
    4. OPTIONS 询问支持的方法
    5. TRACE 路径追踪

    Content-Type 字段的类型是application/json

    或包含自定义请求头。

    非简单请求会在正式通信之前,增加一次HTTP查询请求,称为“预检请求”。

    流程:

    预检请求必须首先使用Options方式发起请求,获取当前的Origin是否在服务器允许的范围,以及支持的请求方式等。

    请求头中除了设置Oirgin字段,还需两个字段:

    1. Access-Control-Request-Method:必选,告诉服务器实际请求将使用的请求方式
    2. Access-Control-Request-Headers:可选,值为逗号分割的字符串,告诉服务器实际请求将携带两个自定义头信息
    预检请求头

    当服务器收到预检请求后,检查了OriginAccess-Control-Request-MethodAccess-Control-Request-Headers 字段以后确认是否允许跨源请求,如果有一项不满足则不允许跨源请求,浏览器会在控制台抛出错误。如果都满足,预检请求的响应头中会包含以下字段:

    1. Access-Control-Allow-Origin:必选,值为请求头中的Origin
    2. Access-Control-Allow-Methods:必选,值为逗号分隔的字符串,表示允许跨域请求的请求方式
    3. Access-Control-Allow-Credentials:可选,值为boolean, 表示是否允许浏览器发送cookie,详情同简单请求
    4. Access-Control-Allow-Headers:可选, 允许跨域请求额外发送的header字段
    5. Access-Control-Max-Age:可选,预检请求的有效时间。在有效时间内,浏览器无须为同一请求再次发起预检请求。需要注意的是,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。
    预检响应头

    服务器通过了“预检”请求以后,就可以发起实际请求了,每次请求都会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

    相关文章

      网友评论

        本文标题:CORS

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