OPTIONS请求详解

2022-07-14  本文已影响0人  沉江小鱼

前言:开发时设置手机代理抓接口请求时,打开H5页面,总是会看到OPTIONS请求,好奇跟常用的GET\POST有何不同,特此学习记录一下。

1. 作用

$ curl -X OPTIONS http://example.org -i
HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST #
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Thu, 14 Jul 2022 06:15:30 GMT
Expires: Thu, 21 Jul 2022 06:15:30 GMT
Server: EOS (vny/0453)
Content-Length: 0

响应报文包含一个 Allow首部字段,该字段的值表明了服务器支持的所有 HTTP 方法

2. 跨域请求

2.1 同源策略

如果两个URL的协议、主机、端口都相同,则称这两个URL同源。以http://music.javaswing.cn/home/index.html为例:

截屏2022-07-14 下午2.00.26.png

作用:这种同源策略,主要是限制html或者它加载的js如何和另一个源的资源进行交互,它能帮助阻隔恶意html,减少可能被攻击的媒介。

2.2 CORS(Cross Origin Resource Sharing) 跨域资源共享

CORS 跨域资源共享是一种机制,使用额外的HTTP头告诉浏览器,让运行在一个origin上的web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议、或端口请求一个资源时,资源会发起一个跨域HTTP请求。

简单来说,就是允许在https://www.aa.com/a/a.html的网页中,去请求https://www.bb.com/bb的接口获取数据。

3. OPTIONS预检请求

3.1 OPTIONS预检请求的触发条件

上面了解了同源策略CORS,终于到了OPTIONS请求。在CORS机制下一个域名A要访问域名B的服务,在使用非简单请求之前,会先进行一个预检请求(浏览器自动发起),检查B服务是否允许跨域请求,服务确认之后,才会发起真正的HTTP请求。

同时,在预检请求的返回中,服务端也可以通知客户端,是否需要携带身份凭证(包括Cookies和HTTP认证相关数据)。

非简单请求:

  1. 请求方法为:PUT/DELETE/CONNECT/OPTIONS/TRACE/PATCH
  2. 设置了首部字段,不包括Accept/Accept-Language/Content-Language/Content-Type/DPR/Downlink/Save-Data/Viewport-Width/Width
  3. Content-Type值不属于application/x-www-form-urlencoded、multipart/form-data、text/plain任何一个;

3.2 OPTIONS预检请求结构

3.2.1 OPTIONS预检请求头

OPTIONS预检请求会携带几个关键的Request Header:

Request Header 作用
Access-Control-Request-Method 告诉服务器实际请求所使用的 HTTP 方法
Access-Control-Request-Headers 告诉服务器实际请求所携带的自定义首部字段
Origin 发起请求的域名 (协议、域名、端口号)
{
  "Host": "app.aaa.com",
  "Origin": "https://m.bbb.com",
  "Access-Control-Request-Method": "GET",
  "Access-Control-Request-Headers": "csrf-token",
  "Connection": "keep-alive",
  "Accept": "*/*",
  "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 zzhunter",
  "Referer": "https://m.caihuoxia.com/",
  "Accept-Language": "zh-CN,zh-Hans;q=0.9",
  "Accept-Encoding": "gzip"
}

3.2.2 OPTIONS预检响应头

预检响应头的关键字段:

response header 作用
Access-Control-Allow-Methods 返回了服务端允许的请求,包含 GET/HEAD/PUT/PATCH/POST/DELETE
Access-Control-Allow-Credentials 允许跨域携带 cookie(跨域请求要携带 cookie 必须设置为 true)
Access-Control-Allow-Origin 允许跨域请求的域名,这个可以在服务端配置一些信任的域名白名单
Access-Control-Allow-Headers 客户端请求所携带的自定义首部字段
{
  "Server": "Tengine",
  "Date": "Thu, 14 Jul 2022 06:25:07 GMT",
  "Content-Type": "text/plain; charset=utf-8",
  "Content-Length": "0",
  "Connection": "keep-alive",
  "Access-Control-Allow-Origin": "https://m.bbb.com",
  "Access-Control-Allow-Credentials": "true",
  "Access-Control-Allow-Headers": "PPU,t,tk,v,uid,Content-Type,Csrf-Token",
  "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
  "Access-Control-Max-Age": "1728000",
  "Set-Cookie": [
    "id58=c5/nR2LPtsOJbsB8a+YHAg==; expires=Sat, 13-Jul-24 06:25:07 GMT; domain=caihuoxia.com; path=/"
  ],
  "P3P": "policyref=\"/w3c/p3p.xml\", CP=\"CUR ADM OUR NOR STA NID\""
}

4. OPTIONS预检请求优化

上面了解到,跨域请求会触发两次请求:OPTIONS预检请求、真正的请求。可以通过缓存OPTIONS预检请求的结果,来减少请求的数量。

Access-Control-Max-Age 这个响应首部表示预检请求的返回结果(即 Access-Control-Allow-MethodsAccess-Control-Allow-Headers 提供的信息) 可以被缓存的最长时间,单位是秒。

如果值为 -1,则表示禁用缓存,每一次请求都需要提供预检请求,即用 OPTIONS 请求进行检测。

5. 总结

OPTIONS预检请求,可用于检测服务器允许的http方法。另外,当发起跨域请求时,非简单请求会导致浏览器自动发起一次OPTIONS预检请求,服务器接受该跨域请求之后,浏览器才继续发起正式请求。

上一篇 下一篇

猜你喜欢

热点阅读