如何响应 HTTP OPTIONS 请求?
Posted
技术标签:
【中文标题】如何响应 HTTP OPTIONS 请求?【英文标题】:How to respond to an HTTP OPTIONS request? 【发布时间】:2012-08-09 05:53:59 【问题描述】:HTTP OPTIONS
方法据说用于确定服务器在给定资源上支持哪些其他方法。鉴于此,我有两个问题:
这个响应是什么样的?我在Public
、Allow
甚至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,应该同时发送Allow
和 Access-Control-Allow-Methods
,还是只发送后者?
我总是返回“允许”,因此不是特殊情况的 CORS。
内容呢?可以提供正文内容吗?
@CMCDragonkai 是的,OPTIONS
可能有内容。来自 RFC 2616:“如果 OPTIONS 请求包括一个实体主体(如 Content-Length 或 Transfer-Encoding 的存在所示),则媒体类型必须由 Content-Type 字段指示。尽管本规范未定义对于这样的主体的任何用途,未来对 HTTP 的扩展可能会使用 OPTIONS 主体在服务器上进行更详细的查询。不支持这种扩展的服务器可能会丢弃请求主体。”
我相信如果要使用 CORS,Allow
和 Access-Control-Allow-Methods
都是必需的。前者指定一般支持哪些方法,后者指定跨域请求允许哪些方法。例如,您可能允许 GET
、POST
、PUT
和 DELETE
用于您自己的来源,但只允许 GET
和 POST
用于跨来源。【参考方案2】:
什么是 HTTP OPTIONS 请求?
客户端请求知道服务器将允许哪些 HTTP 方法,例如GET
、POST
等。
请求
询问特定资源的选项时,请求可能如下所示:
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 Allowed
或501 Not Implemented
。
如何停止接收 HTTP OPTIONS 请求?
如果它来自浏览器,请更新您的 API,使其不会做任何“危险”的事情(例如PUT
或 DELETE
,或 POST
和 application/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 请求?的主要内容,如果未能解决你的问题,请参考以下文章