CORS

CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能。
整个 CORS 通信过程,都有浏览器自动完成,用户无感知,对开发者而言,CORS 和 AJAX 通信无异,前端代码完全一样。浏览器如果发现 AJAX 请求跨域,会自动添加一些附加的头信息,如果是非简单请求,会多出一次 OPTION 请求。实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。

简单请求两大条件

请求方法属于以下三种方式之一

  • HEAD
  • GET
  • POST

HTTP 的头信息不超出以下几种字段

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值 application/x-www-urlencodemultipart/form-datatext/plain

简而言之,简单请求就是简单的 HTTP 方法和简单的 HTTP 头信息的结合
其实简单请求就是传统的表单请求,规避 CORS 的限制

简单请求

基本流程

浏览器自动在头信息中添加一个 Origin 字段,说明本次请求来源哪个域(协议+域名+端口),服务器会根据这个值,决定是否同意本次请求。
如果 Origin 指定的源,不在许可范围内,服务器会返回一个正常的 HTTP 响应,但响应的头信息不包含 Access-Control-Allow-Origin 字段

withCredentials 属性

CORS 请求默认不包含 Cookie 信息(以及 HTTP 认证信息等),这是为了降低 CSRF 攻击的风险。如果服务器需要拿到 Cookie,这时需要服务器显式指定 Access-Control-Allow-Credentials 字段,告诉浏览器可以发送 Cookie

Access-Control-Allow-Credentials: true

同时,必须在 AJAX 请求中设置 withCredentials 属性。
需要注意的式,如果服务器要求浏览器发送 Cookie,Access-Control-Allow-Origin 不能设为星号,必须指定明确的、与请求页面一致的域名。同时,Cookie 依然遵循同源策略,只有用服务器域名设置的Cookie 才会上传,其他域名的 Cookie 并不会上传,且(跨域)原页面代码中的 document.cookie 也无法读取服务器域名下的 Cookie

非简单请求

预检请求

非简单请求是对服务器提出特殊要求的请求,比如请求方法是 PUTDELETE,或者 Content-Type 字段的类型是 application/json

非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,即预检请求。询问当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 方法和头信息字段。只有得到肯定回复,浏览器才会发出正式的 XMLHttpRequest 请求,否则报错

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!