rewrite规则必须放在server或location块内才能生效,写在http顶层会报错;server块中rewrite先执行并影响location匹配,location块中rewrite仅在匹配后触发,flag决定重定向或内部重写。
rewrite 规则必须放在 server 或 location 块内才能生效,写在 http 块顶层会直接报错:“directive is not allowed here”。关键不在“写了没”,而在“写在哪”和“怎么执行”。
server 块中的 rewrite 在任何 location 匹配前就运行,它修改的是原始请求 URI,从而改变 location 的匹配结果。
rewrite ^/(.*)/$ /$1 permanent;
break 或无 flag 的重写——它可能让本该进 location /api/ 的请求,因 URI 被提前改写而错失匹配last,重写后会重新走一遍 location 匹配流程;用 break 则跳过后续 location 查找,直接处理当前块内指令(如 root 或 proxy_pass)只有请求真正匹配到该 location 时,里面的 rewrite 才会执行。这是最常用、最安全的写法。
/old/page.html 内部映射到 /new/page.html,就写在 location /old/ { ... } 里last:重写后重新匹配 location,利于模块化设计(例如统一由 location ~ .php$ 处理脚本)if 块中嵌套 rewrite,尤其不要写 if ($request_uri ~* ...) —— Nginx 最新明确不推荐,易引发不可预期行为rewrite 后面的 flag 不是可有可无的修饰,它直接决定是“浏览器跳转”还是“服务器内部重写”。
permanent 和 redirect:返回 301/302,地址栏会变,适合域名迁移或 SEO 调整last:URI 改写后,立刻用新路径再找一次 location,适合路径标准化或路由转发break:URI 改写后,停止 location 搜索,直接执行当前块剩余指令,适合简单路径补全(如加前缀)last,但显式写出更清晰、更可控很多 rewrite 看似配置了却不触发,问题往往出在请求根本没走到那块配置里。
server 块:检查 listen 端口、server_name 和 SNI 设置,HTTPS 场景下尤其注意 default_server 是否遗漏location 是否真被选中:用 add_header X-Location-Hit "yes"; 或 return 200 "in /api/"; 快速验证实际进入的是哪个块location ^~ /static/ 会屏蔽掉后面所有 location ~ .js$,即使 JS 文件在 /static/ 下也不会进正则块