不能只用 $request_method != GET 限制静态资源请求,因为 HEAD 同样是安全的 HTTP 方法,被浏览器、CDN 和健康检查广泛使用;错误拒绝 HEAD 会导致资源探测失败、监控异常;正确做法是显式允许 GET 和 HEAD,如 if ($request_method !~ ^(GET|HEAD)$) { return 405; } 或使用 limit_except GET HEAD { deny all; }。

直接用 $request_method != GET 限制静态资源目录的请求方法,**不安全且不完整**。GET 确实是安全读取的典型方法,但 HEAD 同样属于安全、无副作用的读取请求,且被浏览器、CDN、健康检查等广泛使用;而仅拦截非 GET 请求,会错误拒绝 HEAD,导致资源不可访问或监控失败。
为什么不能只判断 != GET
HTTP 安全方法(Safe Methods)包括 GET 和 HEAD —— 它们不应改变服务器状态,适合公开静态资源访问。若配置为:
if ($request_method != GET) { return 405; }则所有 HEAD 请求都会被 405 拒绝,破坏标准行为。例如:
• 浏览器预检资源是否存在(不下载内容)
• CDN 刷新时探测 Last-Modified
• curl -I 或健康探针依赖 HEAD 返回头信息
正确写法:显式允许安全方法
应明确放行 GET 和 HEAD,拒绝其余所有方法:
if ($request_method !~ ^(GET|HEAD)$) {return 405;
}
说明:
• !~ 是正则否定匹配
• ^(GET|HEAD)$ 精确匹配两个字符串,避免误判(如 POST 被当作 GET 的子串)
• 返回 405 Method Not Allowed 符合 HTTP 语义,比 403 更准确
更稳妥的做法:结合 location 和 try_files
单纯 if 块在某些 Nginx 版本中存在限制(如不能嵌套、部分指令不生效),推荐用 location + limit_except 或直接限制:
location /static/ {limit_except GET HEAD {
deny all;
}
# 静态文件服务配置
alias /var/www/static/;
expires 1h;
}
优势:
• limit_except 是专为方法限制设计的指令,语义清晰、行为稳定
• 不受 if 性能与作用域问题影响
• 自动隐式允许 OPTIONS(预检),无需额外处理
额外建议:关闭危险方法的执行能力
即使限制了方法,也需确保静态目录下无法执行脚本(如 .php、.py):
- 禁用 fastcgi_pass / proxy_pass 等代理指令在此 location 中出现
- 添加 location ~ \.(php|py|pl|sh|cgi)$ { deny all; } 子块
- 确认 autoindex off; 关闭目录浏览,防止路径泄露

















