如何响应 HTTP OPTIONS 请求?

Posted

技术标签:

【中文标题】如何响应 HTTP OPTIONS 请求?【英文标题】:How to respond to an HTTP OPTIONS request? 【发布时间】:2012-08-09 05:53:59 【问题描述】:

HTTP OPTIONS 方法据说用于确定服务器在给定资源上支持哪些其他方法。鉴于此,我有两个问题:

这个响应是什么样的?我在PublicAllow 甚至Access-Control-Allow-Methods 标头中看到了带有CSV 列表的示例。他们都需要吗?有什么不同? RFC 2616 在这里似乎不是很有帮助。

使用它来列出资源在非 REST-API 环境中支持的操作是否合适?例如,如果我的ConversionController 支持convert 操作,那么这样的响应是否有意义:

请求:

OPTIONS /conversion HTTP/1.1

回复:

HTTP/1.1 200 OK
...
Allow: CONVERT
...

【问题讨论】:

Allow: CONVERT?? 【参考方案1】:

RFC 2616 定义“允许”(http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.7)。 “公共”不再使用。 “Access-Control-Allow-Methods”在 CORS 规范中定义(参见 http://www.w3.org/TR/cors/)。

【讨论】:

感谢您的澄清。对于 CORS,应该同时发送 AllowAccess-Control-Allow-Methods,还是只发送后者? 我总是返回“允许”,因此不是特殊情况的 CORS。 内容呢?可以提供正文内容吗? @CMCDragonkai 是的,OPTIONS 可能有内容。来自 RFC 2616:“如果 OPTIONS 请求包括一个实体主体(如 Content-Length 或 Transfer-Encoding 的存在所示),则媒体类型必须由 Content-Type 字段指示。尽管本规范未定义对于这样的主体的任何用途,未来对 HTTP 的扩展可能会使用 OPTIONS 主体在服务器上进行更详细的查询。不支持这种扩展的服务器可能会丢弃请求主体。” 我相信如果要使用 CORS,AllowAccess-Control-Allow-Methods 都是必需的。前者指定一般支持哪些方法,后者指定跨域请求允许哪些方法。例如,您可能允许 GETPOSTPUTDELETE 用于您自己的来源,但只允许 GETPOST 用于跨来源。【参考方案2】:

什么是 HTTP OPTIONS 请求?

客户端请求知道服务器将允许哪些 HTTP 方法,例如GETPOST 等。

请求

询问特定资源的选项时,请求可能如下所示:

OPTIONS /index.html HTTP/1.1

或者一般询问服务器时这样:

OPTIONS * HTTP/1.1

回应

响应将包含带有允许方法的Allow 标头:

Allow: OPTIONS, GET, HEAD, POST

为什么服务器会收到 HTTP OPTIONS 请求?

一些 REST API 需要它(但如果您正在定义 API,您就会知道) 浏览器将其作为“预检”请求发送到服务器,以查看服务器是否理解 CORS 攻击者发送它以获取有关 API 的更多信息

如何响应 HTTP OPTIONS 请求?

您可以使用Allowed 标头进行响应,甚至可以在正文中使用document your API。 您可以使用额外的 CORS 定义 Access-Control-Request-* 标头进行响应。 您可以回复405 Method Not Allowed501 Not Implemented

如何停止接收 HTTP OPTIONS 请求?

如果它来自浏览器,请更新您的 API,使其不会做任何“危险”的事情(例如 PUTDELETE,或 POSTapplication/json)。只执行simple requests。

另见

RFC 2616 Section 9: Method definitions MDN Web docs: OPTIONS MDN Web docs: Cross-Origin Resource Sharing (CORS) CORS - What is the motivation behind introducing preflight requests? How to exploit HTTP Methods

【讨论】:

【参考方案3】:

响应标题:“如何响应 HTTP OPTIONS 请求?”要回答这个问题,我想知道您为什么要响应 OPTIONS 请求?谁/什么向您发送了 OPTIONS 请求,为什么? Many public servers respond with some form of "error" or "not allowed" (500, 501, 405)。因此,除非您处于特定情况,您的客户将合理地发送 OPTIONS 请求并期望返回有用/有意义的信息(例如,WebDAV、CORS),否则您可能希望回复:“不要那样做。”

就您关于“OPTIONS /conversion HTTP/1.1”请求的问题而言:除非您知道您的服务器有某个客户端,否则该客户端会将 OPTIONS 请求发送到“/conversion”并期望得到“允许:转换,”答案是否定的:这样回应是没有意义的。我认为确实的大多数实现都支持 OPTIONS 并以“允许”响应,并以标准 HTTP 方法响应。

Here's a great article on the topic.

总结:OPTIONS 会立即出现问题,因为它不支持缓存。替代方案:服务器范围的元数据:尝试well-known URI's。特定于资源:尝试在其响应中使用Link header,或该资源的表示格式的链接。

最后,如果您需要的是服务描述,请查看WADL 或RSDL。

编辑:

dotnetguy 在下面的评论中提出了一个很好的观点:OPTIONS 在某些情况下无疑是有价值的(例如,CORS);我当然不是故意的。

【讨论】:

这篇文章很好,而且很有权威,但请参阅“为什么 HTTPbis 将 OPTIONS 留在里面”和 cmets 部分。使用 CORS,REST 系统应该能够响应 OPTIONS,特别是如果要从基于 javascript 的 Web 应用程序使用 API。 JS 框架在实际 HTTP 调用之前触发“预检”选项请求是很常见的。 当我从 macOS Finder (using Webdav) 连接我的(自写)http 服务器时,我看到了 OPTIONS 请求。

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

如何避免在 express.js auth 中间件中捕获 HTTP OPTIONS 请求

如何使用 Capybara 测试 OPTIONS 请求?

HTTP的请求方法OPTIONS

安全防护:X-Frame-Options(点击劫持)

为啥会有OPTIONS请求

Azure 函数和 HTTP OPTIONS 请求