nginx 不支持重写 http 方法,只能通过 limit_except 或 if + return 拦截非法方法(如 trace/delete)并返回 405/403;limit_except 更安全高效,须置于 location 块中,仅允许显式列出的方法。

Nginx 本身不支持“重写”非法 HTTP 方法(如 TRACE、TRACK、OPTIONS、DELETE、PUT 等)为其他请求,因为 HTTP 方法是请求行的一部分,rewrite 指令只处理 URI 路径,无法修改请求方法。但你可以通过标准且可靠的方式——直接拒绝或拦截这些非法方法,实现“统一拒绝/跳转”的效果。
以下是实用、安全、符合生产规范的配置方式:
使用 limit_except 限制允许的方法
适用于明确只允许 GET、HEAD、POST 的场景(最常见):
location / {
limit_except GET HEAD POST {
deny all;
}
# 其他正常配置,如 root、index、proxy_pass 等
}
✅ 效果:除 GET/HEAD/POST 外的所有方法(如 DELETE、PUT、TRACE)将直接返回 405 Method Not Allowed
⚠️ 注意:limit_except 只能放在 location 块中,且不能嵌套在 if 中
使用 if + return 拦截特定方法(需谨慎)
虽然 if 在 location 中可用,但仅建议用于简单判断(Nginx 官方不推荐复杂 if):
location / {
if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$) {
return 405; # 或 return 403; 或 return 302 /forbidden.html;
}
}
✅ 可灵活控制响应码或跳转目标(如 return 302 /403.html;)
⚠️ 风险:$request_method 是只读变量,此处用法安全;但避免在 if 中混用 rewrite、set 或多个条件
强制拦截高危方法(如 TRACE、TRACK)
某些老版本客户端或扫描器会发 TRACE,存在信息泄露风险(HTTP TRACE 可被用于 XST 攻击):
if ($request_method = TRACE) {
return 405;
}
if ($request_method = TRACK) {
return 405;
}
? 放在 server 或 http 块中即可全局生效(无需每个 location 重复)
返回自定义错误页而非裸状态码
配合 error_page 提升用户体验或审计友好性:
error_page 405 /405.html;
location = /405.html {
internal;
root /usr/share/nginx/html;
}
这样用户看到的是友好的提示页,而不是默认的 Nginx 405 页面。
补充:为什么不能用 rewrite 处理方法?
-
rewrite作用对象是$uri(即路径部分),例如/api/user→/v2/user - 请求方法(
GET/PUT)属于 HTTP 请求行第一行,由 Nginx 解析后直接交给后续模块(如ngx_http_core_module),不可被rewrite修改或“重写” - 尝试用
rewrite ... last或break对方法做“转换”,完全无效,Nginx 会忽略
不复杂但容易忽略











