Nginx-UrlRewrite

一、引言:URL不只是地址,更是用户体验与安全的门面

你是否遇到过这些问题:

  • 网站改版后,旧链接全部失效,导致用户收藏夹和搜索引擎索引"404"?
  • 想要将所有 HTTP 流量强制跳转到 HTTPS,但又不想在代码里写一堆判断?
  • 希望隐藏真实的后端接口路径(如 /api/v1/user),对外暴露更简洁的 URL(如 /user)?
  • 需要根据请求参数或客户端类型(PC/手机)返回不同的内容?

这些问题的答案,都指向同一个强大的 Nginx 功能------URL Rewrite(URL重写)

它就像一个智能的"交通指挥官",能在请求到达后端应用之前,对 URL 进行修改、重定向或内部跳转。本文将带你从语法基础到十大经典场景,彻底掌握这项核心技能。

💡 核心价值
精通 URL Rewrite,你就能优雅地处理网站迁移、提升SEO、增强安全性,并构建极其灵活的路由规则


二、核心基石:rewrite 指令详解

Nginx 的 URL 重写功能由 ngx_http_rewrite_module 模块提供,其核心是 rewrite 指令。

基本语法

复制代码
rewrite <regex> <replacement> [flag];
  • <regex>: Perl 兼容的正则表达式 (PCRE),用于匹配请求的 URI。
  • <replacement> : 重写后的 URI。可以使用 $1, $2... 来引用正则中的捕获组。
  • [flag]: 可选标志位,控制重写后的行为。这是最容易混淆但也最关键的部分。

四大核心标志位(Flag)深度解析

标志位 作用 类比
last 停止当前 server 块内的 rewrite 检查,并重新搜索 location "内部重写"。浏览器地址栏不变,服务器内部用新 URI 重新匹配 location
break 停止当前 server 块内的 rewrite 检查,不再重新搜索 location "内部中断"。直接使用当前重写后的 URI 处理请求,通常用于静态文件映射。
redirect 返回 302 临时重定向 "临时搬家"。浏览器地址栏会变成新的 URL。
permanent 返回 301 永久重定向 "永久搬家"。浏览器和搜索引擎会更新书签和索引。

关键区别lastbreak内部操作 ,对用户不可见;redirectpermanent外部重定向,会触发浏览器跳转。


三、十大经典应用场景实战

场景一:HTTP 强制跳转 HTTPS(SEO友好)

复制代码
server {
    listen 80;
    server_name www.example.com;
    # 永久重定向到HTTPS
    return 301 https://$server_name$request_uri;
    # 或者用rewrite
    # rewrite ^(.*)$ https://$server_name$1 permanent;
}

最佳实践 :优先使用 return 指令,因为它更高效、语义更清晰。

场景二:网站改版,旧URL平滑迁移(301重定向)

复制代码
# 旧文章页: /blog/post?id=123
# 新文章页: /article/123.html
rewrite ^/blog/post$ /article/$arg_id.html? permanent;

# 更复杂的路径映射
rewrite ^/old-category/(.*)$ /new-category/$1 permanent;

注意$arg_id 是 Nginx 内置变量,用于获取 id 参数的值。

场景三:隐藏真实路径,美化URL(内部重写)

复制代码
# 对外暴露 /user/123
# 内部实际请求 /api/v1/user?id=123
location /user/ {
    rewrite ^/user/(\d+)$ /api/v1/user?id=$1 last;
    proxy_pass http://backend;
}

用户看到的是干净的 /user/123,后端收到的是带参数的传统接口。

场景四:根据设备类型(PC/手机)返回不同内容

复制代码
# 检测User-Agent
if ($http_user_agent ~* "(mobile|android|iphone|ipod)") {
    rewrite ^(.*)$ $1/mobile/ last;
}

location / {
    root /var/www/html;
    # PC用户访问 /index.html
    # 手机用户访问 /mobile/index.html
}

场景五:阻止特定爬虫或恶意请求

复制代码
if ($http_user_agent ~* "bad-bot|spam-crawler") {
    return 403;
}

# 阻止访问 .env, .git 等敏感文件
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

场景六:统一URL格式(带/或不带斜杠)

复制代码
# 将 /page 重定向到 /page/ (目录形式)
rewrite ^([^.]*[^/])$ $1/ permanent;

场景七:实现多级域名到路径的映射

复制代码
# user1.example.com -> example.com/user/user1
# user2.example.com -> example.com/user/user2
if ($host ~* "^([a-z0-9-]+)\.example\.com$") {
    set $username $1;
    rewrite ^(.*)$ /user/$username$1 last;
}

场景八:API版本控制

复制代码
# /v2/api/... -> /api/v2/...
rewrite ^/v2/(.*)$ /api/v2/$1 last;

场景九:防盗链(防止图片被其他网站直接引用)

复制代码
location ~* \.(jpg|jpeg|png|gif)$ {
    valid_referers none blocked *.yourdomain.com yourdomain.com;
    if ($invalid_referer) {
        return 403;
        # 或者返回一个占位图
        # rewrite ^/.*$ /images/placeholder.png break;
    }
}

场景十:配合动静分离,处理SPA路由

复制代码
location / {
    root /var/www/app;
    try_files $uri $uri/ @rewrites;
}

location @rewrites {
    # 所有未匹配到文件的请求,都重写到 index.html
    rewrite ^(.*)$ /index.html last;
}

这是 Vue/React 等单页应用(SPA)在 history 模式下的标准配置。


四、性能与最佳实践

  1. 慎用 if :Nginx 官方文档有句名言:"If is Evil "。if 指令在 location 块中行为复杂,容易出错。能用 location 匹配就不要用 if
  2. 优先 return :对于简单的重定向(如 301/302),returnrewrite 更高效。
  3. 避免循环 :确保你的重写规则不会导致无限循环。例如,重写 /old/new,但 /new 又被重写回 /old
  4. 测试先行:在生产环境部署前,务必在测试环境中充分验证你的规则。

五、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
大树8810 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠10 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质11 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工12 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智12 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_12 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉13 小时前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦14 小时前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
java_cj14 小时前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei14 小时前
linux 系统目录详解
linux·运维·服务器