什么是CORS? 为什么需要 CORS
CORS 全称 Cross-Origin Resource Sharing, 即跨域资源共享。
出于安全考虑,浏览器限制了跨域的 HTTPS 请求。
CORS 机制
具体来说, CORS 机制
- 使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
- 允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制
根据是否可能对服务器数据产生副作用,浏览器会选择是否发起一个预检请求 preflight request
, 对应请求方法为 options
,,从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP认证 相关数据。
简单请求(不会触发 CORS 预检请求)
满足所有下述条件,则该请求可视为“简单请求”,
- 使用下列方法之一:
- GET
- HEAD
- POST
- 除了被用户代理自动设置的首部字段(例如 Connection,User-Agent)和在 Fetch 规范中定义为 禁用首部名称 的其他首部,允许人为设置的字段为 Fetch 规范定义的 对 CORS 安全的首部字段集合。该集合为:
- Accept
- Accept-Language
- Content-Language
- Content-Type (需要注意额外的限制) Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
- 请求中的任意 XMLHttpRequest 对象均没有注册任何事件监听器;XMLHttpRequest 对象可以使用 XMLHttpRequest.upload 属性访问。
- 请求中没有使用 ReadableStream 对象。
预检请求
注意 如果要发送凭证信息,需要设置 XMLHttpRequest.withCredentials = true;
CORS 相关 headers
响应字段
- Access-Control-Allow-Origin 指定了允许访问该资源的外域 URI
- Access-Control-Expose-Headers 服务器把允许浏览器访问的头放入白名单
- Access-Control-Max-Age 指定了preflight请求的结果能够被缓存多久
- Access-Control-Allow-Credentials 指定了当浏览器的 credentials 设置为 true 时是否允许浏览器读取 response 的内容
- Access-Control-Allow-Methods 用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
- Access-Control-Allow-Headers 用于预检请求的响应。其指明了实际请求中允许携带的首部字段。
请求字段
- Origin 表明预检请求或实际请求的源站。
- Access-Control-Request-Method 将实际请求所使用的 HTTP 方法告诉服务器。
- Access-Control-Request-Headers 将实际请求所携带的首部字段告诉服务器