HTTPQUERY
English

OPTIONS

用法

OPTIONS 请求用于获取目标资源允许的方法和能力,而不对资源执行任何操作。服务器以列出所支持方法的 Allow 请求头进行响应。

当使用星号(*)作为请求目标时,请求作用于整个服务器,而非某个特定资源。

OPTIONS * HTTP/1.1
Host: api.example.re

CORS 预检

OPTIONS 在实际中最常见的用途是 CORS 预检请求。在发送使用了 CORS 安全列表集合之外的方法、自定义请求头,或安全列表集合(application/x-www-form-urlencoded、multipart/form-data、text/plain)之外的 Content-Type 的跨域请求之前,浏览器会自动向目标服务器发送一个 OPTIONS 请求。该预检用于检查服务器是否允许实际请求。

预检请求包含 Origin、Access-Control-Request-Method,以及可选的 Access-Control-Request-Headers。服务器以 Access-Control-Allow-Origin、Access-Control-Allow-Methods 和 Access-Control-Allow-Headers 进行响应,以示批准。

资源能力

客户端查询某个特定资源允许的方法。服务器以 204 No Content 及一个 Allow 请求头进行响应。

请求

OPTIONS /articles HTTP/1.1
Host: api.example.re

响应

HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD, POST, DELETE

服务器范围查询

使用 * 作为目标可揭示服务器总体上支持的方法,与任何特定资源无关。

请求

OPTIONS * HTTP/1.1
Host: api.example.re

响应

HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD

CORS 预检

浏览器准备一个带有自定义 X-Request-ID 请求头的跨域 PUT 请求。在发送实际请求之前,浏览器会发出一个预检 OPTIONS 请求,以确认服务器允许来自请求源的该方法和请求头。

预检请求

OPTIONS /api/data HTTP/1.1
Host: api.example.re
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Request-ID

预检响应

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Request-ID
Access-Control-Max-Age: 86400

Access-Control-Max-Age 的值告知浏览器将预检结果缓存 86,400 秒(一天),从而避免对同一端点重复发送预检请求。

安全

OPTIONS 响应中包含一个列出资源所支持的每个方法的 Allow 请求头。这属于轻微的信息泄露,安全扫描器常将启用的 OPTIONS 端点标记为一项发现。完全禁用 OPTIONS 并非可行的解决方案,因为 CORS 预检请求需要 OPTIONS 才能工作。

推荐的做法是将 Allow 请求头限制为每个端点实际需要的方法。一个接受 GET 和 POST 的资源,不应在 Allow 列表中声明 DELETE 或 PUT。

一些框架支持通过 X-HTTP-Method-Override 请求头将 PUT、PATCH 或 DELETE 隧穿到 POST 请求中。这会绕过基于方法的访问控制,如果该功能未经明确启用和审计,则是一个安全隐患。

为避免不必要的预检请求,应将跨域请求保持在”简单”请求的标准内:仅使用 GET、HEAD,或使用了安全列表请求头和安全列表内容类型的 POST。使用 Content-Type: application/json 总会触发预检。Access-Control-Max-Age 可缓存预检结果,以减少重复的 OPTIONS 往返。