咱们能够看下 MDN 中的一段描述:前端
★HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通讯选项。客户端能够对特定的 URL 使用 OPTIONS 方法,也能够对整站(经过将 URL 设置为“*”)使用该方法。chrome
”
简单来讲,就是能够用 options 请求去嗅探某个请求在对应的服务器中都支持哪一种请求方法。跨域
在前端中咱们通常不会主动发起这个请求,可是每每你能够看到浏览器中相同的请求发起了 2 次,如图:浏览器
其实,这是由于在跨域的状况下,在浏览器发起"复杂请求"时主动发起的。跨域共享标准规范要求,对那些可能对服务器数据产生反作用的 HTTP 请求方法(特别是 GET 之外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否容许该跨域请求。服务器确认容许以后,才发起实际的 HTTP 请求。缓存
某些请求不会触发 CORS 预检请求,这样的请求通常称为"简单请求",而会触发预检的请求则称为"复杂请求"。安全
GET、HEAD、POST
时发的请求Accept/Accept-Language/Content-Language/Content-Type/DPR/Downlink/Save-Data/Viewport-Width/Width
Content-Type
的值仅限于下列三者之一,即application/x-www-form-urlencoded、multipart/form-data、text/plain
application/x-www-form-urlencoded、multipart/form-data、text/plain
关键字段 | 做用 |
---|---|
Access-Control-Request-Method | 告知服务器,实际请求将使用 POST 方法 |
Access-Control-Request-Headers | 告知服务器,实际请求将携带的自定义请求首部字段 |
如:服务器
Access-Control-Request-Method: POSTAccess-Control-Request-Headers: X-PINGOTHER, Content-Type
关键字段 | 做用 |
---|---|
Access-Control-Allow-Methods | 代表服务器容许客户端使用什么方法发起请求 |
Access-Control-Allow-Origin | 容许跨域请求的域名,若是要容许全部域名则设置为 * |
Access-Control-Allow-Headers | 将实际请求所携带的首部字段告诉服务器 |
Access-Control-Max-Age | 指定了预检请求的结果可以被缓存多久 |
当咱们发起跨域请求时,若是是简单请求,那么咱们只会发出一次请求,可是若是是复杂请求则先发出 options 请求,用于确认目标资源是否支持跨域,而后浏览器会根据服务端响应的 header 自动处理剩余的请求,若是响应支持跨域,则继续发出正常请求,若是不支持,则在控制台显示错误。微信
因而可知,当触发预检时,跨域请求便会发送 2 次请求,既增长了请求数,也延迟了请求真正发起的时间,严重影响性能。app
因此,咱们能够优化 Options 请求,主要有 2 种方法。ide
Access-Control-Max-Age
字段,那么当第一次请求该 URL 时会发出 OPTIONS 请求,浏览器会根据返回的 Access-Control-Max-Age 字段缓存该请求的 OPTIONS 预检请求的响应结果(具体缓存时间还取决于浏览器的支持的默认最大值,取二者最小值,通常为 10 分钟)。在缓存有效期内,该资源的请求(URL 和 header 字段都相同的状况下)不会再触发预检。(chrome 打开控制台能够看到,当服务器响应 Access-Control-Max-Age 时只有第一次请求会有预检,后面不会了。注意要开启缓存,去掉 disable cache 勾选。)options 请求就是预检请求,可用于检测服务器容许的 http 方法。当发起跨域请求时,因为安全缘由,触发必定条件时浏览器会在正式请求以前自动先发起 OPTIONS 请求,即 CORS 预检请求,服务器若接受该跨域请求,浏览器才继续发起正式请求。
最后
欢迎加我微信(winty230),拉你进技术群,长期交流学习...
欢迎关注「前端Q」,认真学前端,作个专业的技术人...