Skip to content
📈0️⃣

Nginx 实现 URL 重写

Nginx

Nginx 是一个高性能的 Web 服务器和反向代理服务器,以其稳定性、高并发处理能力和灵活的配置而广受欢迎。它可以通过 URL 重写来实现对请求的 URL 进行修改和转换。

语法格式

在 Nginx 中,URL 重写是通过在 location 块中使用 rewrite 指令来实现的。rewrite 指令可以根据预定义的规则,将请求中的 URL 进行修改或重定向。

rewrite 指令的语法格式为:

nginx
rewrite regex replacement [flag];

其中,regex 是正则表达式,用于匹配请求的 URL;replacement 是替换后的 URL;flag 是可选的,用于指定重写后的行为。

重写示例

URL 重写是指在接收客户端请求时,根据预定义的规则,将请求中的 URL 进行修改或重定向的过程。以下是一些常用的 URL 重写示例:

  1. 简单重定向:
nginx
location /old-url {
    rewrite ^/old-url$ /new-url redirect;
}

这个示例中,当请求的 URL 是/old-url 时,将其重定向到/new-url。

  1. 隐藏文件扩展名:
nginx
location / {
    if (-f $request_filename) {
        break;
    }
    rewrite ^/(.*)$ /$1.html last;
}

如果请求的 URL 对应的文件不存在,将默认尝试在 URL 末尾添加.html 扩展名来查找文件。以实现隐藏 URL 中文件扩展名的目的。

  1. 路径重写:
nginx
location /foo/ {
    rewrite ^/foo/(.*)$ /$1 last;
}

这个示例中,访问/foo/路径下的资源时,将/foo/从 URL 中去除,只保留后面的内容。

  1. 参数重写:
nginx
location /search {
    rewrite ^/search\?keyword=(.*)$ /search/$1 last;
}

当请求的 URL 形式为/search?keyword=xxx 时,将其转换为/search/xxx 的形式。

需要注意的是,URL 重写规则的顺序很重要,Nginx 会按照配置文件中 location 块出现的顺序依次匹配,并执行第一个匹配成功的规则。

总结来说,Nginx 中的 URL 重写允许我们通过配置规则,实现对请求的 URL 进行修改、重定向和转换,以满足特定的需求。以上示例只是一部分常用的 URL 重写场景,实际应用中可能需要根据具体需求进行更复杂的配置。

项目实战

vitepress 项目配置

要求:

  1. 请求 https://zichin.com/ 时,重定向到 https://zichin.com/blog/
  2. 请求 https://zichin.com/blog/ 时,返回 /blog/docs/.vitepress/dist/ 路径下对应的资源
nginx
location = / {
    rewrite ^/$ /blog last;
}

location = /blog {
    rewrite ^/blog$ /blog/ last;
}

location ^~ /blog/ {
    rewrite ^/blog(.*)$ /blog/docs/.vitepress/dist$1 break;
    try_files $uri $uri/ /blog/docs/.vitepress/dist/index.html $uri/blog/docs/.vitepress/dist/index.html;
}
  1. location = /:精确匹配根路径。

    rewrite ^/$ /blog last;:匹配根路径"/",重定向至/blog,并停止当前 location 块的匹配。

  2. location = /blog:精确匹配/blog 路径。

    rewrite ^/blog$ /blog/ last;:匹配/blog 路径(结尾没有斜杠),重定向至/blog/(添加斜杠),并停止当前 location 块的匹配。

  3. location ^~ /blog/:前缀匹配/blog/路径。

    rewrite ^/blog(.*)$ /blog/docs/.vitepress/dist$1 break;:匹配/blog 路径后的任意内容,并重写 URL 为/blog/docs/.vitepress/dist + 匹配到的内容,然后终止重写过程。

    try_files $uri $uri/ /blog/docs/.vitepress/dist/index.html $uri/blog/docs/.vitepress/dist/index.html;:依次尝试寻找与请求 URI 匹配的文件、目录,以及特定路径下的 index.html 文件。如果都找不到则返回 404。

网站多项目配置

要求:

  1. 请求 https://zichin.com/entry/ 时,返回 /entry/ 路径下对应的资源
  2. 请求 https://zichin.com/work/ 时,返回 /www/work/dist/ 路径下对应的资源
  3. 请求 https://zichin.com/dopdf/ 时,返回 /www/dopdf/dist/ 路径下对应的资源
nginx
location ^~ /entry {
    rewrite ^/entry(.*)$ /www/entry$1 break;
    try_files $uri $uri/ $uri/index.html;
}

location ^~ /work {
    rewrite ^/work(.*)$ /www/work/dist$1 break;
    try_files $uri $uri/ /www/work/dist/index.html;
}

location ^~ /dopdf {
    rewrite ^/dopdf(.*)$ /www/dopdf/dist$1 break;
    try_files $uri $uri/ /www/dopdf/dist/index.html;
}
  1. location ^~ /entry:前缀匹配/entry 路径。

    rewrite ^/entry(.*)$ /www/entry$1 break;:匹配/entry 路径后的任意内容,并重写 URL 为/www/entry + 匹配到的内容,然后终止重写过程。

    try_files $uri $uri/ $uri/index.html;:依次尝试寻找与请求 URI 匹配的文件、目录,以及在当前目录下的 index.html 文件。若都找不到则返回 404。

  2. location ^~ /work:前缀匹配/work 路径。

    rewrite ^/work(.*)$ /www/work/dist$1 break;:匹配/work 路径后的任意内容,并重写 URL 为/www/work/dist + 匹配到的内容,然后终止重写过程。

    try_files $uri $uri/ /www/work/dist/index.html;:依次尝试寻找与请求 URI 匹配的文件、目录,以及/www/work/dist 目录下的 index.html 文件。若都找不到则返回 404。

  3. location ^~ /dopdf:前缀匹配/dopdf 路径。

    rewrite ^/dopdf(.*)$ /www/dopdf/dist$1 break;:匹配/dopdf 路径后的任意内容,并重写 URL 为/www/dopdf/dist + 匹配到的内容,然后终止重写过程。

    try_files $uri $uri/ /www/dopdf/dist/index.html;:依次尝试寻找与请求 URI 匹配的文件、目录,以及/www/dopdf/dist 目录下的 index.html 文件。若都找不到则返回 404。

每个 location 块定义了不同的 URL 路径匹配规则和对应的操作,包括重写 URL 和尝试查找文件。根据这些规则,Nginx 会根据请求的 URL 路径匹配到对应的 location 块,并执行相应的操作。