nginx重定向配置的核心就一句话:用return指令处理站点级跳转,用rewrite指令处理路径级跳转,选对301或302状态码,改完配置先测试再reload。这篇文章把常用的配置写法、两个指令的区别、典型场景的完整配置,以及配置之后不生效的排查思路一次讲清楚。
nginx重定向配置的三种核心写法
nginx里做重定向,日常够用的无非三种写法,别贪多,把每种适用场景记牢,比背一堆花哨参数实在。
第一种,return指令。 这是最推荐的方式,简单直接,nginx收到请求后立刻返回状态码和跳转地址,性能开销最小,适合整站迁移、http跳https、域名换新这类没有复杂匹配逻辑的场景。
server {
listen 80;
server_name old-example.com;
return 301 https://new-example.com$request_uri;
}
第二种,rewrite指令。 rewrite更像“改写”请求路径,常用于单条URL的精准跳转,比如旧博客文章的链接映射到新地址,它支持正则匹配,灵活性高,但要注意rewrite之后nginx会重新走一遍location匹配流程,性能和行为都比return复杂。
location /old-post {
rewrite ^/old-post/(.)$ /new-post/\ permanent;
}
第三种,location块搭配proxy_pass。 严格说这不叫重定向,是反向代理转发,客户端地址栏不变,但如果你的需求是“同一个路径,不同环境返回不同内容”,用这个思路处理比跳转更合适。
location /api {
proxy_pass http://backend-server;
}
选择建议:能写return就别碰rewrite,行业共识认为return在性能、可读性和可维护性上都优于rewrite,rewrite只在需要复杂正则改写时才有存在意义,nginx官方文档同样建议优先使用return。
nginx 301重定向配置与rewrite规则有什么区别
这两个指令的差异,是nginx重定向配置不生效怎么办排查过程中最常见的迷惑点,理解它们的底层逻辑,才能写出符合预期的规则。
return和rewrite的执行时机不同。 return在nginx处理请求的rewrite阶段直接终

止流程,立刻响应,rewrite同样在rewrite阶段执行,但执行完会带着改写后的URI重新进入location匹配循环,这个差异直接导致一个后果:rewrite之后可能会有新的location规则命中,如果那个location里还有rewrite,会继续循环,而return不存在这个问题。
正则能力不同。 return支持变量拼接,但不擅长路径内的复杂匹配;rewrite支持完整的正则表达式,可以捕获分组然后重组URL,以下是两者的核心语法对比:
| 维度 | return | rewrite |
|---|---|---|
| 基本语法 | return 状态码 [地址] | rewrite 正则 替换地址 [标志] |
| 匹配方式 | 不支持正则,支持变量 | 支持正则,支持捕获分组 |
| 执行结果 | 直接返回响应,流程终止 | 改写URI后重新匹配location |
| 性能开销 | 更低 | 相对更高 |
| 典型场景 | 整站跳转、域名迁移 | 单条URL改写、复杂路径规则 |
nginx 301重定向配置里的permanent标志要写对。 rewrite的最后一个参数,permanent代表301永久跳转,redirect代表302临时跳转,漏写标志,默认走302,搜索引擎对临时跳转和永久跳转的处理逻辑完全不同,细节出错代价不小。
状态码的选择依据需求。 301适用于内容永久迁移,比如网站改版、域名更换;302/307适用于临时调整,比如活动页跳转、A/B测试,选错状态码,轻则搜索引擎收录变慢,重则权重传递失效。
nginx更换域名重定向配置完整指南
域名变更是最常见的重定向需求,旧域名积累的权重和收录,全部靠配置正确的301跳转来传递,这一步做不好,换域名等于从零开始。
旧域名全站301跳新域名。 这是nginx更换域名重定向配置的标准做法,注意把http和https两个入口都覆盖到,同时保留$request_uri把完整路径带过去。
server {
listen 80;
server_name old-example.com www.old-example.com;
return 301 https://new-example.com$request_uri;
}
server {
listen 443 ssl;
server_name old-example.com www.old-example.com;
# SSL证书配置省略
return 301 https://new-example.com$request_uri;
}

http跳https的配置顺序。 先处理80端口的跳转,再处理443端口的业务逻辑,注意不要只配一个80跳443就以为完事了,要检查是否所有旧入口都覆盖到位。
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# 正常业务配置
}
单条URL的精准映射。 旧文章链接结构变了,用rewrite做逐条适配,会比全部301到首页体验好得多,这里推荐用rewrite写正则做批量映射,但务必在测试环境验证好每条规则。
location /article/ {
rewrite ^/article/(\d+)$ /post/\ permanent;
}
配置完成后,验证顺序是:nginx -t检查语法,curl -I看返回状态码是否301,再检查Location头的目标地址是否正确,数据验证可以看搜索引擎的搜索词报告和404日志变化。
nginx重定向配置不生效的五个排查方向
配置写了但跳转没反应,优先级最高的是检查nginx是否真的重载了配置,运行nginx -s reload成功并不代表所有worker进程都切换到了新配置,旧进程可能还在处理连接。
规则顺序导致覆盖。 server块内rewrite和return的执行有先后顺序,正则匹配时location的选择也有优先级(精确匹配>前缀匹配>正则匹配>通配前缀),比如把location /old放在location /之前,规则会被后者干扰。
server_name和listen端口匹配问题。 最隐蔽的情况是写了listen 80 default_server,但请求的Host头匹配到了另一个server块,配置规则看起来对,实际根本没执行,排查方法是运行nginx -T查看实际加载的完整配置,确认对应server块确实存在。
浏览器和CDN缓存了旧跳转。 301是永久跳转,浏览器和CDN会缓存结果,你改了配置,但用户端拿到的还是旧地址的缓存,测试时用无痕窗口、加?v=时间戳参数或直接curl避开缓存,能快速确认是不是这个原因。

rewrite循环导致nginx报500。 规则写得不严谨,比如把/news/(.)重写到/posts/$1,而/posts/又有规则把它指回/news/,nginx会触发循环检测,直接返回500,排查日志时看到rewrite or internal redirection cycle,基本就是这个原因。
SSL证书未覆盖新域名。 如果你做了域名跳转但没有为新域名配置SSL证书,https访问会先报证书错误,跳转根本走不到,先把证书问题解决,再排查跳转逻辑。
排查时的几条实用命令
nginx -t # 检查配置文件语法 nginx -T | grep server_name # 查看实际生效的完整配置 nginx -s reload # 平滑重载配置 curl -I http://old-example.com/old-path # 查看响应头中的状态码和Location tail -f /var/log/nginx/error.log # 实时查看错误日志
nginx重定向配置常见问题解答
nginx重定向配置会影响网站GEO吗?
会影响,而且影响很大,搜索引擎爬虫会跟随跳转链接,301会把旧页面的权重传递给新地址,但前提是路径一一对应,全部跳转到首页会让旧页面的收录和权重全部丢失,配置完成后,在搜索引擎后台提交站点改版或域名变更工具,能加速收录更新。
nginx正则重定向里的中文字符怎么处理?
中文字符在URL里是百分号编码后的形式,比如/分类/对应/categoty/(实际是百分号编码),正则匹配时直接写编码后的字符更可靠,或者用$request_uri整体带过去,不建议在rewrite正则里直接写中文,匹配容易出问题。
nginx重定向配置和CDN跳转哪个更好?
取决于你的需求层级,CDN层面做跳转,离用户更近,响应更快,还能在源站之前拦截流量,降低服务器压力,但CDN跳转通常只支持简单规则,复杂的正则匹配和中途修改路径,还是得靠nginx的rewrite来实现,多数情况下,CDN跳转适合入口级的粗粒度规则,nginx重定向适合源站上的细粒度控制,两者可以搭配使用,nginx重定向配置的核心就是规则清晰、状态码准确、测试充分,把这三件事做好,大部分跳转需求都能稳定落地。
