跨域资源共享(CORS)概述
跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,它使用额外的HTTP头部让浏览器知道一个网页被允许访问来自另一个源服务器上的资源。这种机制允许web应用程序进行跨域访问控制,从而使跨域数据安全传输。
什么情况下需要CORS?
跨域资源共享标准允许在以下场景中使用跨域HTTP请求:
- 由XMLHttpRequest或Fetch发起的跨域请求:当网页尝试通过XMLHttpRequest或Fetch API从与其不同源的服务器请求资源时,需要CORS机制来允许或拒绝这种跨域请求。
- Web字体:在CSS中通过@font-face使用跨域字体资源时,也需要CORS来确保字体资源可以被正确加载。
- WebGL贴图:在使用WebGL进行图形渲染时,如果尝试将跨域的Images或video画面绘制到canvas上,同样需要CORS的支持。
- 样式表(使用CSSOM):通过CSS对象模型(CSSOM)访问或修改跨域样式表时,也可能需要CORS的授权。
CORS的工作原理
CORS标准新增了一组HTTP头部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。这些头部字段包括:
- Origin:表明预检请求或实际请求的源站。
- Access-Control-Request-Method:用于预检请求,将实际请求所用的HTTP方法告诉服务器。
- Access-Control-Request-Headers:用于预检请求,将实际请求所携带的首部字段告诉服务器。
服务器响应时,可以使用以下头部字段来控制跨域访问:
- Access-Control-Allow-Origin:指定哪些源站可以访问资源。可以是一个具体的源站,也可以是“*”表示接受所有源站的请求。
- Access-Control-Allow-Methods:用于预检请求的响应,指明实际请求所允许的HTTP方法。
- Access-Control-Allow-Headers:用于预检请求的响应,指明实际请求所允许携带的首部字段。
- Access-Control-Allow-Credentials:表示是否允许发送Cookie。如果为true,则实际请求的cookie可以包含在请求中一起发送给服务器。
- Access-Control-Expose-Headers:让服务器把允许浏览器访问的头放入白名单,这样浏览器就能够通过getResponseHeader访问这些响应头了。
- Access-Control-Max-Age:指定预检请求的结果能够被缓存多久。
CORS请求的分类
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
对于简单请求,浏览器直接发出CORS请求,在头信息中增加一个Origin字段。服务器响应时,如果允许跨域访问,则在响应头中包含Access-Control-Allow-Origin字段。
- 非简单请求:不满足简单请求的条件即为非简单请求。非简单请求需要先发送一个OPTIONS预检请求,预检请求完成后才发送实际的请求。预检请求中,浏览器会包含Access-Control-Request-Method和Access-Control-Request-Headers头部字段,告诉服务器实际请求将使用的HTTP方法和头部字段。服务器响应时,如果允许跨域访问,则在响应头中包含Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers字段。
CORS的注意事项
- CORS不支持IE10以下的浏览器。
- 如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号(*),必须指定明确的、与请求网页一致的域名。
- Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传。
- 跨源原网页代码中的document.cookie无法读取服务器域名下的Cookie。
通过理解和应用CORS机制,web开发者可以更好地控制跨域资源的访问,确保数据的安全传输和应用的正常运行。