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-urlencode
、multipart/form-data
、text/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
非简单请求
预检请求
非简单请求是对服务器提出特殊要求的请求,比如请求方法是 PUT
或 DELETE
,或者 Content-Type
字段的类型是 application/json
非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,即预检请求。询问当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 方法和头信息字段。只有得到肯定回复,浏览器才会发出正式的 XMLHttpRequest 请求,否则报错
必须 注册 为本站用户, 登录 后才可以发表评论!