CROS
CROS(Cross-origin Resource Sharing)是一个W3C标准,全称是"跨域资源共享"。
它允许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源
使用的限制。
什么是同源
同源策略(same-origin policy)是浏览器安全的基石。其目的是为了保护用户信息的安全,防止网站恶意的窃取数据。
不同源下,浏览器不允许这三种行为发生:
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
同源指的是网址的三个相同
:
- 协议相同
- 域名相同
- 端口相同
使用http://www.example.com/dir/page.html
,来举例说明:
- 协议名是
http://
,常用的协议有:http(s)://
(超文本传输协议)、ftp://
(传输文件协议)、file://
(获取本地文件协议)、mailto://
(发邮件协议)、tel://
(打电话协议)、sms://
(发短信协议);- 域名是
www.example.com
;- 端口号是
80
,http、https、ftp、file、mailto、tel、sms等协议都有默认端口号,所以可以省略;/dir/page.html
是资源路径
通过以下的例子,可以更加快速的理解什么是同源:
http://www.example.com/dir2/other.html
:同源http://example.com/dir/other.html
:不同源(域名不同)http://v2.www.example.com/dir/other.html
:不同源(域名不同)http://www.example.com:81/dir/other.html
:不同源(端口不同)
CORS两种请求方式
当网站源地址和资源请求地址非同源,就出现了跨域请求。当出现跨域请求后,请求依然可以发送到服务器且服务器也会返回数据,但是会被浏览器给拦截。对于跨域问题,可以使用CORS
来解决,使用CORS时,HTTP请求分为两种情况:简单请求和复杂请求。
简单请求:
满足以下三点即可:
- HTTP请求方法为GET、POST或HEAD;
- HTTP请求头只能包含
Accept, Accept-Language, Content-Language, Content-Type
或Last-Event-ID
; - ContentType的值只能为以下三种:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
复杂请求:
非简单请求,就是复杂请求。在跨域情况下,浏览器在发起复杂请求之前,必须首先使用OPTIONS
方法发起一个预检请求(preflight rquest),从而获知服务端是否允许改跨域请求。服务器确认允许后,才发起实际的HTTP请求。该要求是在跨域共享标准规范中规定的,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。
HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。简单来说,就是可以用 options 请求去嗅探某个请求在对应的服务器中都支持哪种请求方法。
OPTINOS 方法的关键请求头字段
request header 的关键字段
关键字段 | 作用 |
---|---|
Origin | 表示请求来自哪个源 |
Access-Control-Request-Method(必须) | 告知服务器,实际请求将使用 HTTP的哪种方法 |
Access-Control-Request-Headers | 告知服务器,实际请求将携带的自定义请求首部字段 |
举例如下如:
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
response header 的关键字段
关键字段 | 作用 |
---|---|
Access-Control-Allow-Methods(必须) | 表明服务器支持的所有跨域请求的方法 |
Access-Control-Allow-Headers | |
Access-Control-Allow-Origin |
参考链接:
浏览器同源政策及其规避方法 - 阮一峰的网络日志 (ruanyifeng.com)