OPTION 请求的作用
关于浏览器的 同源策略(Same-Origin Policy)长话短说:
同源策略出于安全考虑,限制了不同源(即不同的协议、域名或端口)之间的资源交互。这是为了防止恶意网站访问或篡改另一个源的数据。
然而,随着Web应用的发展,经常需要从不同的源(例如API服务)获取数据,于是 CORS(Cross-Origin Resource Sharing 跨域资源共享)机制就诞生了
CORS 允许服务器通过设置特定的HTTP响应头来决定哪些源可以访问它的资源,比如:Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers 等等
而 OPTION 请求 就是用来询问服务器是否允许该跨源请求的。这样做可以过滤掉不被服务器允许的请求,从而减少不必要的网络通信和潜在的安全风险。通过这种方式,CORS机制确保了跨源请求的安全性,同时为服务器提供了灵活的控制手段。
所以你可以用一句话概括 OPTION 请求 的作用: OPTION 请求 就是为了询问服务器是否允许此次的跨域请求。
什么情况下会发起 OPTION请求
这里要明确两点:
- 并不是所有的post请求都会发起
OPTION 请求的,我发现很多人都认为只要是post请求都会发OPTION 请求 - 并不是跨域请求都会发起
OPTION 请求
只有同时满足下面两个条件时,浏览器才会自动发起 OPTION 请求
- 跨域请求
- 非简单请求
什么是跨域请求
请求的目标资源与发起请求的页面的源(协议、域名、端口)不同,就是跨域请求。
什么是简单请求
查看 W3C(World Wide Web Consortium 万维网联盟) 可知,满足下面所有条件者,即是简单请求
- 使用GET、HEAD或POST方法
- 不包含非CORS安全列表的自定义请求头,CORS安全列表中的头包括:
- Accept
- Accept-Language
- Content-Language
- Content-Type(但有限制,具体往下看)
- 如果是POST请求,Content-Type头必须是以下三个值之一
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
为什么不是所有的请求都发送 OPTION 请求
如果所有请求都发一个 OPTION 请求,又会出现一些问题,比如说:
- 性能问题:每个请求之前都需要发送一个额外的OPTIONS请求,这会导致网络延迟增加。
- 服务器负担:大量的OPTIONS请求会增加服务器的负担,需要处理更多的请求,这可能导致服务器资源的浪费,尤其是在高流量的情况下。
- 用户体验:对于用户来说,每次请求都需要等待预检完成,这会导致应用的响应时间变长,影响用户体验。
所以基于上面几个问题 CORS 把请求分为 简单请求 和 非简单请求,其中 简单请求 被认为对服务器是安全的,并且不会引起对服务器的未授权访问或数据的意外更改,简单请求特性使得它们不需要通过预检来确认服务器的CORS策略,从而简化了跨源请求的处理流程。
OPTION 请求的实现原理
OPTIONS请求在CORS(跨源资源共享)中的实现原理涉及浏览器和服务器之间的交互。以下是详细的步骤和原理:
-
浏览器检测请求类型:
- 当浏览器发现一个跨源AJAX请求(如使用
XMLHttpRequest或fetch),它会首先检查这个请求是否为简单请求。
- 当浏览器发现一个跨源AJAX请求(如使用
-
发送预检请求:
- 如果请求是非简单请求,浏览器会先发送一个OPTIONS请求到服务器。这个预检请求目的是询问服务器是否允许实际的跨源请求。
-
预检请求的请求头:
- 预检请求会包含以下请求头:
Access-Control-Request-Method:声明实际请求将使用的HTTP方法。Access-Control-Request-Headers(如果需要):声明实际请求将使用的非CORS安全列表的请求头。
- 预检请求会包含以下请求头:
-
服务器处理预检请求:
- 服务器接收到OPTIONS请求后,会检查请求头中的
Access-Control-Request-Method和Access-Control-Request-Headers,然后根据内部配置的CORS策略来决定是否允许实际的请求。 - 服务器的响应会包含以下CORS相关的响应头:
Access-Control-Allow-Origin:指定允许的源。Access-Control-Allow-Methods:指定允许的HTTP方法。Access-Control-Allow-Headers:指定允许的请求头。Access-Control-Max-Age:预检请求结果的缓存时间。Access-Control-Allow-Credentials:是否允许发送凭证。
- 服务器接收到OPTIONS请求后,会检查请求头中的
-
浏览器处理预检响应:
- 浏览器检查OPTIONS请求的响应头,如果服务器允许跨源请求,则浏览器会记住这个决定,并在一定时间内(由
Access-Control-Max-Age决定)缓存这个结果,然后发起真实请求 - 如果服务器不允许跨源请求,浏览器会阻止实际的请求,并显示错误。
- 浏览器检查OPTIONS请求的响应头,如果服务器允许跨源请求,则浏览器会记住这个决定,并在一定时间内(由