一、nginx rewrite 与 proxy_pass区别
rewrite 和 proxy_pass 都是 Nginx 的常用指令,但它们的功能和使用场景有所不同。
1、rewrite:是一个用来修改请求 URI 的指令。在 Nginx 收到一个请求后,rewrite 指令可以基于特定的条件改变这个请求的 URI,可能是改变文件路径,可能是重定向到一个新的地址。基本的语法为 rewrite regex replacement [flag] 其中 regex 是要匹配的正则表达式,replacement 是匹配的结果要被替换的内容。例如,rewrite ^(/download/.*)/media/(.*)$ $1/mp3/$2,这个会把 "/download/media/abc.mp3"这样的 URL 替换为 "/download/mp3/abc.mp3"。负载越大,对硬件的要求就越高。
2、proxy_pass:这个指令告诉 Nginx 将收到的请求转发到其他的服务器。在做反向代理时经常会用到此命令。例如,proxy_pass http://localhost:8000; 这个配置就会把所有请求转发到运行在 localhost:8000 上的服务器。负载越高,对网络的需求就越大。
而它们之间的主要区别就是,rewrite 是对请求 URL 的修改,而不改变请求的目的地,而 proxy_pass 是不改变 URL,但是改变了请求的后端服务器,这两个指令通常结合起来使用,用以实现一些特定的需求。在实际运用中我们经常看到这两者一起使用,以满足定制化路由的逻辑。
例如:
location / {
rewrite ^/abc/(.*)$ /xyz/$1 break;
proxy_pass http://localhost:8000;
}
这个配置中,客户端请求的 URL "/abc/test" 会被重写为 "/xyz/test" ,然后再被转发到 localhost:8000 这个服务器上。
问题一:问题来了,那么,使用rewrite后,假设我的配置是location / { rewrite ^/abc/(.*)$ /xyz/$1 break; proxy_pass http://localhost:8000; },那么我在浏览器输入http://10.10.1.2/abc/mm,访问后,浏览器地址是否会变成http://10.10.1.2/xyz/mm?
不会,Nginx的rewrite指令在这种情况下只会更改传递给后端服务器的URI,并不会影响浏览器的地址栏。在浏览器地址栏输入http://10.10.1.2/abc/mm,服务器会接收到这个请求并通过rewrite规则将其更改为/xyz/mm,然后将其转发到proxy_pass设置的地址http://localhost:8000/xyz/mm。但这并不会更改浏览器的地址栏。
如果你想要在rewrite后更改浏览器的地址栏,你需要发送一次HTTP重定向。例如,以下配置可以在rewrite时发送HTTP 301永久重定向:
rewrite ^/abc/(.*)$ /xyz/$1 permanent;
在此情况下,当浏览器尝试访问http://10.10.1.2/abc/mm,服务器会返回HTTP 301响应和新地址http://10.10.1.2/xyz/mm。然后浏览器会在地址栏更新新地址并请求新地址。请注意,这将使浏览器显示新URL,但也将导致两次请求——一次是原始请求,另一次是重定向到新URL的请求。
问题二:那么,使用rewrite后,假设我的配置是location / { rewrite ^/abc/(.*)$ /xyz/$1 break; },那么我在浏览器输入http://10.10.1.2/abc/mm,访问后,浏览器地址是否会变成http://10.10.1.2/xyz/mm?
不会,同样的,即使你没有使用 proxy_pass,Nginx 的 rewrite 指令也只是在服务器内部重写 URL,而不会影响浏览器地址栏显示的 URL。
在你的例子中,当你在浏览器输入 http://10.10.1.2/abc/mm,Nginx 会接收到这个请求,并将请求 URL 通过 rewrite 规则改写为 "/xyz/mm"。然后,Nginx 会在本地查找这个新的 URL 对应的资源。这个过程对客户端浏览器是不可见的,因此浏览器地址栏还是会显示原来输入的 URL。
如果你要想改变浏览器的地址栏显示的 URL,你需要显式地发出一个重定向响应,比如使用 HTTP 的 301 或 302 状态码。这可以通过在 rewrite 指令后面添加 redirect 或 permanent 标志来实现。例如,
rewrite ^/abc/(.*)$ /xyz/$1 permanent;
这样,当一个请求匹配这个 rewrite 规则时,Nginix 会向客户端浏览器发出一个 301(永久重定向)响应,浏览器接收到这个响应之后,会自动将地址变为新的 URL 并重新发送请求。
问题三:rewrite ^/abc/(.*)$ /xyz/$1 permanent;和rewrite ^/abc/(.*)$ /xyz/$1 redirect;是什么区别
rewrite ^/abc/(.*)$ /xyz/$1 permanent; 和 rewrite ^/abc/(.*)$ /xyz/$1 redirect; 这两个Nginx配置的主要区别在于重定向的HTTP状态码。
-
permanent: 生成一个HTTP 301 Moved Permanently响应。这个响应是永久性的,告诉客户端(比如浏览器)这个资源已经被永久的移动到了新的位置,以后应该直接去新的位置查找这个资源。
-
redirect:生成一个HTTP 302 Moved Temporarily响应。这个响应告诉客户端这个资源被暂时移动到了新的位置,但是可能以后还会回到原来的位置。
因此,在实际使用中,你应该根据实际情况选择恰当的响应。如果你知道资源永久的移动到了新的位置,那么应该使用permanent;如果你知道资源只是暂时移动到新的位置,那么应该使用redirect。