OPTIONS 请求过多

Posted

技术标签:

【中文标题】OPTIONS 请求过多【英文标题】:Too many OPTIONS requests 【发布时间】:2018-01-13 05:12:10 【问题描述】:

在我的应用程序中,前端(使用 axios 的 ReactJS,如果重要的话)对后端(Node/Express,如果重要的话)进行一些 API 调用。在所有响应中,服务器确实以Access-Control-Allow-Origin:* 响应(这是一个测试环境,将进行适当的更改以允许生产中的特定来源)。

在 Chrome 开发人员工具网络选项卡中,我观察到对于每个请求说POST /assetsPOST /filtersPUT /media 等,都会发送一个预检的 OPTIONS 请求。现在我明白from here 的原因了,这很好。

OPTIONS 请求标头

OPTIONS /api/v1/content/bb54fbf52909f78e015f/f91659797e93cba7ae9b/asset/all 
HTTP/1.1
Host: XX.X.XX.XXX:5000
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36     (Khtml, like Gecko) Chrome/59.0.3071.115 Safari/537.36    
Access-Control-Request-Headers: authorization,content-type
Accept: */*
DNT: 1
Referer: http://localhost:3000/main/93f1ced0f15f35024402/assets
Accept-Encoding: gzip, deflate
Accept-Language: en,en-US;q=0.8,mr;q=0.6

响应标头

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Vary: Access-Control-Request-Headers
Access-Control-Allow-Headers: authorization,content-type
Date: Sat, 05 Aug 2017 10:09:16 GMT
Connection: keep-alive

我的观察是,这实际上是针对每个请求发送的,并且是重复的,即即使再次发出相同的请求(立即或以其他方式)。

我的问题是

    这一定是件坏事(即,它会导致任何性能问题,即使是轻微的)?

    为什么浏览器不记得同一服务器、同一请求的标头响应?

    我在前端或后端是否缺少任何配置以使其具有粘性?

【问题讨论】:

【参考方案1】:

您需要发送Access-Control-Max-Age 标头来告诉浏览器可以将其他Access-Control-* 标头缓存那么多秒:

Access-Control-Max-Age: 600

【讨论】:

谢谢,效果很好。不过,我确实有一个后续问题。如您链接的文档中所述,此设置有一个超时,因浏览器而异,即 FF 为 24 小时,Chrome 为 10 分钟。这有什么道理吗?我知道我们不希望将设置无限期缓存,但是将其打开 2 小时或 4 小时等有什么风险。还有一个问题,因为在文档中不清楚,是否缓存根据独特的要求制定还是通用的。我的意思是,如果服务器为 /media 资源发送标头,是否会考虑 /user? @SubhashDike 回复。超时:鉴于 Fx 和 Chrome 之间的差异如此之大,我想这只是一个任意的截止值,供应商认为这是谨慎和性能之间的良好折衷。 W3C CORS spec 只是说“物品不能停留 [...] 不合理的时间”。 @SubhashDike 回复。粒度:根据W3C CORS spec,是per-URL。但我不确定浏览器是否真的遵循该规范,因为它们通常与 W3C 关系不温不火。

以上是关于OPTIONS 请求过多的主要内容,如果未能解决你的问题,请参考以下文章

http options请求

tomcat启用options请求

为啥会有OPTIONS请求

面试题杂记02-OPTIONS请求

HTTP中的OPTIONS请求

OPTIONS 请求身份验证