如何响应HTTP OPTIONS请求?

99
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
...

3
允许:转换。 - Pacerier
对于阅读上面评论并且感到困惑的任何人:HTTP方法只是一些字符串,具有一些预定义的值,请参考RFC 9110。因此,使用CONVERT是完全有效的,并且符合规范;事实上,RFC甚至指出方法名是区分大小写的,"因为它可能被用作具有区分大小写方法名的基于对象的系统的网关"。这意味着您甚至可以使用过程名作为HTTP方法进行RPC! - undefined
3个回答

28

什么是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头响应,甚至在正文中记录您的API
  • 您可以使用其他CORS定义的Access-Control-Request-*头响应。
  • 您可以使用405 Method Not Allowed501 Not Implemented响应。

如何停止收到HTTP OPTIONS请求?

  • 如果它来自浏览器,则更新您的API,使其不执行任何“危险”操作(例如PUTDELETE,或使用application/jsonPOST)。只执行简单请求

另请参阅


23

1
谢谢您的澄清。在CORS的情况下,应该发送AllowAccess-Control-Allow-Methods两者,还是只发送后者? - FtDRbwLXw6
1
我总是会返回“Allow”,因此不需要特殊处理CORS。 - Julian Reschke
10
内容是什么?正文内容可以提供吗? - CMCDragonkai
2
@CMCDragonkai 是的,OPTIONS 可能会有内容。根据 RFC 2616:“如果 OPTIONS 请求包括实体正文(由 Content-Length 或 Transfer-Encoding 指示),则必须通过 Content-Type 字段指示媒体类型。尽管此规范未定义任何用途,但 HTTP 的未来扩展可能使用 OPTIONS 正文在服务器上进行更详细的查询。不支持此类扩展的服务器可能会丢弃请求正文。” - bishop
我认为如果你想使用CORS,AllowAccess-Control-Allow-Methods都是必需的。前者指定了一般支持的方法,后者指定了允许跨域请求的方法。例如,你可能允许自己的来源使用GETPOSTPUTDELETE,但只允许跨域使用GETPOST - Mikko Rantalainen

10
作为对标题“如何响应HTTP OPTIONS请求”的回应:要回答这个问题,我想知道你为什么想要响应OPTIONS请求?是谁/什么在向您发送OPTIONS请求,为什么? 许多公共服务器会以某种形式(500、501、405)响应“错误”或“不允许”。因此,除非您处于一个特定的情况,您的客户端将合理地发送OPTIONS请求并期望得到有用/有意义的信息返回(例如WebDAV,CORS),否则您可能希望回复:“不要这样做。”
关于“OPTIONS /conversion HTTP / 1.1”请求的问题:除非您知道有一些客户端会向“/conversion”发送OPTIONS请求并期望响应“Allow: CONVERT”,否则答案是否定的:以那种方式进行响应是没有意义的。我认为大多数支持OPTIONS并响应“Allow”的实现都会响应标准的HTTP方法。 这里有一篇很棒的文章
概述:OPTIONS存在问题,因为它不支持缓存。替代方案:服务器级元数据:尝试使用知名URI。资源特定:尝试在其响应中使用Link header或在该资源的表示格式中使用链接。

最后,如果您想要服务描述,请查看WADLRSDL

编辑:

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


4
这篇文章很好,而且有权威性,但请看“为什么HTTPbis保留OPTIONS”和相关评论部分。使用CORS,REST系统应该能够响应OPTIONS请求,特别是如果API将来会在JavaScript网页应用中使用的话。常见的JS框架在实际进行HTTP调用前会发送一个“预检”OPTIONS请求。 - Sudhanshu Mishra
当我使用macOS Finder(使用Webdav)连接我的(自编写的)http服务器时,我看到了OPTIONS请求。 - Joe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接