应使用 limit_except 指令限制 HTTP 请求方法,它专用于按方法控制访问,仅允许列出的方法(如 GET、HEAD),其余返回 405;不可用 allow/deny(仅限 IP 控制)或慎用 if + $request_method。

在 macOS 下使用 Nginx 限制 HTTP 请求方法(如只允许 GET 和 HEAD,禁止 POST、PUT 等),不能依赖 allow/deny 指令 —— 因为这两个指令仅用于控制 IP 访问权限,**不适用于请求方法限制**。
正确方式:用 limit_except 块
limit_except 是 Nginx 中专用于按 HTTP 方法限制访问的指令,语义清晰、配置简洁,且兼容所有现代 Nginx 版本(包括 macOS 上通过 Homebrew 安装的版本)。
- 它定义一个作用域,在其中 只允许列出的方法,其余方法默认被拒绝(返回 405 Method Not Allowed)
- 可嵌套在
location、server或http块中,推荐放在具体location内以精准控制 - 支持的方法包括:
GET、HEAD、POST、PUT、DELETE、PATCH、OPTIONS、TRACE
示例:仅允许静态资源目录接受 GET 和 HEAD 请求
location /static/ {
alias /usr/local/var/www/static/;
limit_except GET HEAD {
deny all;
}
}
此时访问 /static/test.json 使用 POST 会直接返回 405 Not Allowed,无需额外日志或重写逻辑。
替代方案:用 if + $request_method(慎用)
虽然可用 if ($request_method !~ ^(GET|HEAD)$) { return 405; } 实现类似效果,但 Nginx 官方明确建议避免在 location 外使用 if,且该写法在某些边界场景(如带 rewrite 的配置)中行为不可靠。
- 仅在
location内使用相对安全,但仍不如limit_except直观和健壮 - 注意:
if在server级别可能引发意外匹配,尤其配合正则location时 - 若必须用
if,确保把它放在最内层location中,并测试OPTIONS、HEAD等隐式方法是否受影响
验证与调试技巧
修改配置后务必执行标准流程:
- 运行
sudo nginx -t检查语法(macOS 下通常需sudo权限读取配置) - 重载生效:
sudo nginx -s reload(不要用stop/start,避免中断服务) - 用
curl快速验证:curl -X POST http://localhost/static/test.txt应返回405 - 查看错误日志定位问题:
tail -f /usr/local/var/log/nginx/error.log(Homebrew 默认路径)
常见误区提醒
很多用户误以为 allow/deny 能控制方法,其实它们只处理客户端 IP:
-
allow 127.0.0.1; deny all;→ 控制谁可以访问,跟POST或GET无关 -
limit_except不影响请求头、参数或 body,只校验请求行中的 method 字符串 -
OPTIONS请求常被前端预检触发,若业务需要 CORS,记得在limit_except中显式加入OPTIONS或单独配置响应头

















