azl397985856 / fe-interview

宇宙最强的前端面试指南 (https://lucifer.ren/fe-interview)
Apache License 2.0
2.84k stars 260 forks source link

【每日一题】- 2020-04-07 - http 请求方法 options 方法有什么用? #110

Closed azl397985856 closed 4 years ago

libin1991 commented 4 years ago

预检请求

HEternally commented 4 years ago

用于获取目的资源所支持的通信选项

maydaylike commented 4 years ago

发起一个预检请求到服务区,以获知服务器是否允许该实际请求。可以避免跨域请求对服务器的用户数据产生未预期的影响。

suukii commented 4 years ago

OPTIONS 方法有什么用?

  1. 用来查询服务端支持哪些请求方法,服务端的响应中会在头部 Allow 字段中列出所支持的请求方法(如:Allow: OPTIONS, GET, HEAD, POST)
  2. 在 CORS 中使用 OPTIONS 方法来实现预请求

为什么要使用 OPTIONS 方法?

要说为什么使用 OPTIONS 请求,得从浏览器的同源策略和跨域说起,如果两个 URL 的域名、协议或者端口有任一个不一样,那就产生了跨域,出于安全考虑,浏览器禁止了跨域访问,也就是不许在一个域中使用 JS 向另一个域发送请求。

但有时候跨域请求也是很有必要的,于是就有了 CORS 来解决跨域的问题。

CORS 的实现机制是这样的,浏览器先给服务端发送一个预请求,跟服务端说,“我接下来要给你发一个请求了,它长这样这样,你看能不能接受”,服务端收到预请求,就会作出判断并给出响应了,浏览器再根据服务端的回应决定要不要发送真正的请求。

为什么不直接发送真正的请求呢?服务端不接受就直接驳回好啦。首先,安全问题,要是那请求里有什么攻击性的代码呢。其次,节省资源吧(我猜的),OPTIONS 请求传输数据少点。

OPTIONS 细节

OPTIONS 方法会携带两个头部字段(当然还有其他):

  1. Access-Control-Request-Method 告诉服务端,真正的请求发送时,会使用什么请求方法
  2. Access-Control-Request-Headers 告诉服务端,真正的请求发送时,会携带哪些自定义头部字段

然后服务端就可以决定是否要接收这样的请求,然后在响应中使用 Access-Control-Allow-Methods 来指明哪些请求方法是可以被接受的(这个字段和 Allow 有些像,但是只能用于 CORS)

request

Access-Control-Request-Method: POST
Access-Contro-Request-Headers: X-PINGOTHER, Content-Type

意思就是,我(浏览器)接下来要发的那个请求,会用 POST 方法来发送,还要带着 X-PINGOTHER 和 Content-Type 两个自定义头部字段,你(服务端)就说你接不接受吧。

response

Access-Control-Allow-Methods: POST, GET, OPTIONS 
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

POST, GET, OPTIONS 请求我(服务端)都能接受,请求里还准许带 X-PINGOTHER, Content-Type 这两个头部

feikerwu commented 4 years ago

抄下MDN作业

  1. 检测服务器所支持的请求方法
  2. CORS 中的预检请求

说下自己理解, 第一点,检测服务器所支持的请求方法,是为了降低服务器负载,比如server端某个资源只支持get/post请求,如果没有options,你发了个delete请求过来,server端就需要做计算处理这个请求,浪费资源

第二点,预检请求,是为了保护服务器安全,或者说资源安全。先发一个options请求,告知client服务端支持的请求源,请求中支持header等,如果没有你下次要发的请求 请求源不在我给你列表 或者 你的请求中有些奇奇怪怪的东西,你就不要发给我了,我怕有刁民想害朕。虽然我不知道它到底有没有害,我不管,我不接受,你在源端就给我干掉好了。

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.