美文网首页
CORS跨域资源共享(Cross-origin resouce

CORS跨域资源共享(Cross-origin resouce

作者: AlldayCode | 来源:发表于2020-10-20 16:41 被阅读0次

一、CORS简介

    CORS是一个W3C的标准,全称“跨域资源共享”(Cross-origin resource sharing)。
    CORS允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源请求的限制。CORS需要浏览器和服务器的共同支持。目前所有浏览器都支持此功能,IE浏览器版本不得低于IE10。
    CORS的整个通信过程都是浏览器自动完成的,不需要用户参与。对于开发者来说,CORS通信与AJAX同源通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时甚至会多出一次附加请求,但是用户不会有感觉,因为过程由浏览器自动完成。实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以进行跨源通信。

二、CORS请求

浏览器将CORS请求分为两类,简单请求(simple request)和非简单请求(not-so-simple request),浏览器对两种请求的处理方式是不同的。满足以下条件为简单请求,否则为非简单请求。

简单请求成立条件:

  1. 请求方法为以下一种
  • HEAD
  • GET
  • POST
  1. HTTP请求头不超出以下字段
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type
    限定值:application/x-www-form-urlencoded、multipart/form-data、text/plain

三、简单请求

对于简单请求浏览器的处理方式是在请求头添加Origin字段并发送CORS请求。

以下为CORS请求的例子的RequestHeads:

Accept: */*
Origin: http://127.0.0.1:8082
Referer: http://127.0.0.1:8082/h5/corsRequest.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36

请求头中Origin字段用来说明本次请求来自的源(协议://域名:端口)。服务器根据这个值来决定是否同意这个请求。

  1. 不同意请求
    如果指定了Origin请求源,不在服务端的许可范围内,服务器会返回一个正常的HTTP响应。浏览器检查响应头没有Access-Control-Allow-Origin字段,即表示服务端不同意此次请求,浏览器抛出异常被XMLHttpRequest的onerror函数捕获。此错误无法通过响应状态码进行判断,尽管服务端不同意请求,请求仍正常响应。

  2. 同意请求
    如果指定的Origin请求源在服务端的许可范围内,请求响应头会附加几个字段,字段如下:

Access-Control-Allow-Origin: http://127.0.0.1:8082
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Sivan
Content-Type: text/html; charset=utf-8

以上响应头字段中有三个是有关于CORS请求的,都以Access-Control-开头。

  • Access-Control-Allow-Origin
    此字段是必须的。值为请求头的Origin或*号(*号表示接受任意源的CORS请求)。
  • Access-Control-Allow-Credentials
    此字段可选。值为布尔值,表示是否允许发送Cookie。默认情况下CORS请求不包含Cookie。设置为true即明确表示服务端允许Cookie包含在CORS请求中,共同发送给服务端。此字段的值固定为true,如果不需要浏览器发送Cookie,删除字段即可。

CORS请求默认不发送Cookie和Http认证信息。如果要把这些信息共同发送到服务端,必须要服务端同意(指定Access-Control-Allow-Credentials:true请求头字段)和浏览器同意(在AJAX请求指定withCredentials:true属性)。如果省略withCredentials属性,部分浏览器还是会发送Cookie,可以显式关闭withCredentials(withCredentials:false)。
注意:如果要发送cookie则Access-Control-Allow-Origin请求头字段不能为*号,必须指明与CORS请求源一致的域名。同时Cookie依然遵守同源策略,只有以服务端域名设置的才会发送,且(跨源)原网页代码中的document.cookie也无法读取服务端域名下的Cookie。

  • Access-Control-Expose-Headers
    此字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()函数只能拿到六个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。获取其他响应头字段需要在Access-Control-Expose-Headers指定。以上例子表示服务端指定Siven响应头字段可获取(Access-Control-Expose-Headers: Sivan)。

四、非简单请求

非简单请求即对服务端有特殊要求的请求,例如请求方法是PUT或DELETE之类的,或Content-Type是application/json等。
非简单请求会在正式通信前发送预检(preflight)请求,询问服务端当前网页所在的域名是否在CORS许可范围内,以及请求头和Content-Type是否在允许范围内。在得到服务端的肯定答复后会发送正式的XMLHttpRequest请求,反之报错。

  1. 预检请求(preflight)


    预检请求(preflight)

预检请求使用的请求方法是OPTIONS,表示这个请求是用于询问的。以下列出请求头里的相关字段:

  • Origin
    字段必选。预检请求关键字段,表明预检请求的源。
  • Access-Control-Request-Headers
    字段必选。用于表明浏览器端的CORS请求时用到的HTTP方法。
  • Access-Control-Request-Method
    字段非必选。字段为逗号分隔字符串。用于表明浏览器端的CORS请求会使用到的额外请求头字段。
  1. 预检请求响应
    服务端收到预检请求后,检查Origin、Access-Control-Request-Headers、Access-Control-Request-Method是否在跨源请求的范围内,并作出响应。
  • 预检请求不通过
    如果服务端否认了预检请求,作出正常的HTTP响应,但是响应头没有任何相关CORS的字段,响应状态码一般为403无权访问。此时浏览器通过判断得知服务端否定了预检请求,触发错误并未XMLHttpRequest的onerror回调函数捕获,控制台打印出异常。

    预检请求不通过
  • 预检请求通过
    如果服务端确定了预检请求,作出正常回应,响应投中包含CORS相关字段,响应码一般为200。浏览器监听到服务端确定了预检请求则自动发出正式的CORS请求。

    预检请求响应

响应头字段如下:
Access-Control-Allow-Origin
字段必选。预检请求响应关键字段。表示服务端允许CORS请求的源,如果设置为*则表示任意源皆可发送CORS请求(跨源请求)。
Access-Control-Allow-Credentials
字段非必选(布尔值)。与简单请求的含义相同,表示服务端同意接口Cookie。
Access-Control-Allow-Headers
字段可选。如果浏览器请求头包含Access-Control-Request-Headers字段则响应头的Access-Control-Allow-Headers字段为必选。字段为逗号分隔字符串,用于表明服务端所支持的CORS请求的请求头字段。
Access-Control-Allow-Methods
字段必选。值为逗号分隔字符串。表示服务端接收CORS请求所支持的请求方法。
Access-Control-Expose-Headers
字段可选。值为逗号分隔字符串。与简单请求的含义一致。表示服务端所支持的跨源请求自定义请求头字段。
Access-Control-Max-Age
字段可选。表示本次预检请求的有效期,即在本次预检有效期间(缓存预检请求)将不再发送预检请求。单位为秒。

  1. 正常请求与正常回应
    在服务端通过预检请求之后,如果设置了预检请求有效期,则浏览器发送非简单请求与简单请求的方式一致(直至预检请求失效),请求头附加Origin字段表明请求源,响应头也会有Access-Control-Allow-Origin字段。

相关文章

  • Spring Boot 最简单的解决跨域问题

    跨域问题(CORS) CORS全称Cross-Origin Resource Sharing,意为跨域资源共享。当...

  • HTTP访问控制(CORS)

    什么是CORS? CORS(Cross-Origin Resource Sharing ) 全称“跨域资源共享”,...

  • SpringBoot CORS 跨域 @CrossOrigin

    CORS 跨域共享 跨源资源共享(Cross-origin resource sharing, CORS)是由大多...

  • CORS 跨域资源共享

    CORS (Cross-Origin Resource Sharing) 跨域资源共享 为什么需要 CORS 首先...

  • 跨域CORS

    CORS全称是跨域资源共享(Cross-Origin Resource Sharing),用来解决AJAX跨域请求...

  • CORS跨域服务器设置

    CORS即Cross-Origin Resource Sharing,跨域资源共享 CORS分为两种 一:简单的跨...

  • CORS实现跨域

    1. cors是什么 CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),...

  • 什么是CORS

    CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域...

  • CORS

    CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域...

  • 跨域资源共享CORS详解

    一、CORS是什么 cors全称为跨域资源共享(Cross-origin resource sharing),是一...

网友评论

      本文标题:CORS跨域资源共享(Cross-origin resouce

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