圈小蛙

带有和不带有重定向地址的Nginx重写URL示例

Nginx可以根据目标语法以不同方式处理重写参数(rewrite)。下面是一些如何在Nginx中定义重定向和URL重写的示例。

基本重定向(302暂时移动,302 Moved Temporarily)

创建重定向的最简单形式是在重写URL中附加关键字“redirect”:

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        rewrite ^/$ http://websrv1.qxwa.com/mypage redirect;
    }
}

这将导致HTTP 302暂时移动重定向。在浏览器中,地址栏中的URL将更改为转发的URL。

永久重定向(301永久移动,301 Moved Permanently)

上述302状态有助于快速重定向,但未针对SEO进行优化。如果您创建明确重定向,则应在重写配置的末尾设置永久关键字:

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        rewrite ^/$ http://websrv1.qxwa.com/mypage permanent;
    }
}

这会导致HTTP 301永久移动状态。用户将在浏览器中看到与302重定向相同的体验:地址栏中的URL将更改并显示重定向目标URL。 

使用last或break作为关键字

让我们尝试一下不使用重定向或永久选项,但使用break或last:

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        rewrite ^/$ http://websrv1.qxwa.com/mypage last;
    }
}

尽管重写选项现在设置为最后,但浏览器仍会跟随URL并更改地址栏中的URL。只要重写目标包含http://(或 https://),这就会被视为外部重定向,因此将始终重定向客户端(和浏览器)。

内部地址重写(无重定向)

因此,如果您想将请求的URL保留在浏览器地址栏中,并且只是想重写URL(与Apache Web服务器中的mod_rewrite相同),则必须使用相对路径:

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        rewrite ^/$ /mypage last;
    }
}

这将从文档根目录(/var/www/www.qxwa.com)内的子文件夹/mypage加载www.qxwa.com的网站。 

内部地址重写作为反向代理

但是,如果目标网站是从其他地方加载的,例如从后台的Tomcat上游服务器加载,该怎么办?以下配置涵盖了这一点:

upstream tomcat {
    server 127.0.0.1:8080;
}

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        include proxy-settings.conf;
        proxy_pass http://tomcat;
        rewrite ^/$ /mypage last;
    }
}

首先,所有内容(位置 /)都传递给Tomcat(定义的上游服务器)。然后,根路径 (/) 的重定向正在发生,并且是相对于路径的。

这会导致浏览器的地址URL保持在www.qxwa.com,但从127.0.0.1:8080/mypage加载网站。

使用动态路径进行内部地址重写

有时您可能想更改内部路径,但仍使用所请求URI的(某些部分)。您可以使用括号“()”创建一个选择,然后使用$1引用第一个选择,使用$2引用第二个选择,依此类推。

upstream tomcat {
    server 127.0.0.1:8080;
}

server {
    server_name www.qxwa.com;
    root /var/www/www.qxwa.com;

    location / {
        include proxy-settings.conf;
        proxy_pass http://tomcat;
        rewrite ^/(.*)$ /mypage/$1 last;
    }
}

如果原始请求的URL是http://www.qxwa.com/hello-world,它实际上会从上游服务器加载以下 URL:http://127.0.0.1:8080/mypage/hello-world。

如何验证内部 URI 重写

一些地址重写非常简单 - 但其他地址重写可能要复杂得多。要验证重写的请求URI是什么样子,您可以使用内部Nginx变量并将其显示为响应标头。以下配置显示了将成为Nginx服务器响应一部分的附加标头 Requested-URI和Final-URI:

upstream tomcat {
    server 127.0.0.1:8080;
}

server {
  server_name www.qxwa.com;
  root /var/www/www.qxwa.com;

  location / {
    include proxy-settings.conf;
    proxy_pass http://tomcat;
    rewrite ^/(.*)$ /mypage/$1 break;
    add_header Requested-URI $request_uri always;
    add_header Final-URI $uri always;
  }
}

使用curl查看响应标头时,您可以看到这些标头:

$ curl http://www.qxwa.com/hello-world -I
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Feb 2022 13:00:36 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Requested-URI: /hello-world
Final-URI: /mypage/hello-world
Exit mobile version