Skip to content
导航

CORS

CORS(Cross-Origin Resource Sharing,跨源资源共享),也有译作跨域资源共享。

CORS 机制允许 Web 应用服务器控制跨源访问,从而使跨源数据传输得以安全进行。

请求标头

无须手动设置请求标头。当开发者使用XHR、fetch发起跨源请求时,浏览器会自动设置标头、发送预检请求。

Origin

http
Origin: <origin>

Origin 参数的值为源站 URL origin。它不包含任何路径信息,只是服务器名称。

Access-Control-Request-Method

请求头 Access-Control-Request-Method 出现于预检请求中,用于通知服务器在真正的请求中会采用哪种 HTTP 方法。
因为预检请求所使用的方法总是 OPTIONS ,与实际请求所使用的方法不一样,所以这个请求头是必要的。

http
Access-Control-Request-Method: <method>

Access-Control-Request-Method

请求头 Access-Control-Request-Method 出现于预检请求中,用于通知服务器在真正的请求中会采用哪种 HTTP 方法。
因为预检请求所使用的方法总是 OPTIONS ,与实际请求所使用的方法不一样,所以这个请求头是必要的。

http
Access-Control-Request-Method: <method>

若服务端允许,则应返回响应标头

http
Access-Control-Allow-Methods: <method>[, <method>]*

Access-Control-Request-Headers

请求头 Access-Control-Request-Headers 出现于预检请求中,用于通知服务器在真正的请求中会采用哪些请求头。

http
Access-Control-Request-Headers: <field-name>[, <field-name>]*

若服务端允许,则应返回响应标头

http
Access-Control-Allow-Headers: <header-name>[, <header-name>]*

响应标头

服务器返回的 HTTP 响应头,可以控制浏览器允许这些源访问加载自己的资源。

Access-Control-Allow-Origin

http
Access-Control-Allow-Origin: <origin> | *

允许指定的源访问资源,或对于不需要带身份凭证的请求,指定*允许任意源请求。

Access-Control-Expose-Headers

http
Access-Control-Expose-Headers: <header-name>[, <header-name>]*

对于访问控制请求,浏览器默认只让JS访问Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma这些标头,想要访问更多标头需要服务器配置此响应标头。

Access-Control-Max-Age

http
Access-Control-Max-Age: <delta-seconds>

指定预检请求的结果能够被浏览器缓存多久。

Access-Control-Allow-Credentials

http
Access-Control-Allow-Credentials: true

指定浏览器附带凭证的请求,对应的响应是否让JS能够访问。

简单请求

简单请求不会触发 CORS 预检请求。 对简单请求的条件限制,简单理解就是 <form> 元素能够发出的请求。

当请求满足下述任一条件时,即应首先发送预检请求:

  • 使用了指定任一 HTTP 方法:PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段
  • Content-Type 的值不属于:application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 请求中的 XMLHttpRequestUpload 对象注册了任意多个事件监听器
  • 请求中使用了 ReadableStream 对象

预检请求

不满足简单请求条件的,或者说不能通过<form>元素发出的请求,浏览器就必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。

使用预检请求而不是直接发送实际请求的好处

  • 一是可以避免在服务端错误设置CORS时处理了实际请求,例如删除数据。
  • 二是可以控制浏览器阻止发送不允许的请求、访问响应数据中的敏感信息如自定义标头。

预检请求是由浏览器自动发出的,浏览器开发者工具中看不到预检请求,需要在服务器查看和处理。

一个预检请求和服务端响应的例子

http
OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

参考资料