一、不同’/‘结尾的区别 #
location /api/ {
proxy_pass http://backend:8080/;
}
location /api/ {
proxy_pass http://backend:8080;
}
location /api {
proxy_pass http://backend:8080/;
}
location /api {
proxy_pass http://backend:8080;
}
配置一:带斜杠的路径匹配和目标 URL #
location /api/ {
proxy_pass http://backend:8080/;
}
- 匹配以
/api/开头的请求 - 将请求转发到带有尾部斜杠的目标 URL
- 会替换匹配的路径部分
- 例如:请求
/api/file.jpg会被转发到http://backend:8080/file.jpg
配置二:带斜杠的路径匹配但目标 URL 不带尾部斜杠 #
location /api/ {
proxy_pass http://backend:8080;
}
- 匹配以
/api/开头的请求 - 将请求转发到不带尾部斜杠的目标 URL
- 会将整个原始 URI 附加到目标 URL 后面
- 例如:请求
/api/file.jpg会被转发到http://backend:8080/api/file.jpg
配置三:不带斜杠的路径匹配但目标 URL 带尾部斜杠 #
location /api {
proxy_pass http://backend:8080/;
}
- 匹配以
/api开头的请求(包括/api和/api/...) - 将请求转发到带有尾部斜杠的目标 URL
- 会替换匹配的路径部分
- 例如:当请求
/api/file.jpg时,Nginx 会将匹配的路径部分/api替换为http://backend:8080/。由于目标 URL 已经包含了尾部斜杠,而原始请求中/api之后也有一个斜杠,所以最终转发的 URL 会变成http://backend:8080//file.jpg(注意这里有两个连续的斜杠) - 请求
/api会被转发到http://backend:8080/
这种配置可能会导致一些 Web 服务器在处理双斜杠时出现问题,虽然大多数现代服务器能够正确处理这种情况。
如果想避免这个问题,可以使用以下两种方式之一:
- 使用配置一(如果只需要匹配
/api/开头的请求) - 使用配置四,确保 proxy_pass 的 URL 不以斜杠结尾
配置四:不带斜杠的路径匹配和目标 URL 也不带尾部斜杠 #
location /api {
proxy_pass http://backend:8080;
}
- 匹配以
/api开头的请求(包括/api和/api/...) - 将请求转发到不带尾部斜杠的目标 URL
- 会将整个原始 URI 附加到目标 URL 后面
- 例如:请求
/api/file.jpg会被转发到http://backend:8080/api/file.jpg - 请求
/api会被转发到http://backend:8080/api
总结 #
- 当
proxy_pass的 URL 以/结尾时,Nginx 会替换匹配的路径部分 - 当
proxy_pass的 URL 不以/结尾时,Nginx 会将完整的原始 URI 附加到目标 URL location /api/只匹配以/api/开头的请求location /api匹配以/api开头的所有请求,包括/api本身
二、Nginx proxy_pass URL 末尾斜杠的影响 #
在 Nginx 配置中,proxy_pass 指令的 URL 是否以斜杠 / 结尾会对请求路径的处理产生重要影响:
有斜杠结尾的情况 #
当 proxy_pass 的 URL 以斜杠结尾时(如 http://backend/),Nginx 会将请求的路径部分原样附加到目标 URL 后面。
例如:
location /api/ {
proxy_pass http://backend/;
}
当请求 /api/users 时,会被代理到 http://backend/users(注意 /api/ 被去掉了)
无斜杠结尾的情况 #
当 proxy_pass 的 URL 不以斜杠结尾时(如 http://backend),Nginx 会将完整的请求路径(包括 location 匹配的部分)附加到目标 URL 后面。
例如:
location /api/ {
proxy_pass http://backend;
}
当请求 /api/users 时,会被代理到 http://backend/api/users(保留了完整路径)
实际应用示例 #
- 有斜杠结尾:适用于希望去掉前缀的情况
location /api/ {
proxy_pass http://backend:8080/; ## 请求 /api/users 会代理到 http://backend:8080/users
}
- 无斜杠结尾:适用于希望保留完整路径的情况
location /api/ {
proxy_pass http://backend:8080; ## 请求 /api/users 会代理到 http://backend:8080/api/users
}
Nginx rewrite指令 #
Nginx的rewrite指令是一个强大的URL重写工具,它允许你根据正则表达式匹配和替换URL。这个功能在网站重构、URL规范化和实现URL友好化方面非常有用。
rewrite指令基本语法 #
rewrite regex replacement [flag];
- regex: 用于匹配URI的正则表达式
- replacement: 替换的URI
- flag: 可选标志,控制重写后的行为
常用的flag #
- last - 停止处理当前的ngx_http_rewrite_module指令集,并开始搜索与更改后的URI相匹配的location
- break - 停止处理当前的ngx_http_rewrite_module指令集
- redirect - 返回302临时重定向
- permanent - 返回301永久重定向
使用示例 #
基本重写 #
location /old/ {
rewrite ^/old/(.*)$ /new/$1 permanent;
}
这会将所有以/old/开头的请求永久重定向到/new/开头的URL。
带条件的重写 #
if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
如果请求的文件不存在,将请求重写到index.php并传递原始URI作为参数。
多级重写 #
location /download/ {
rewrite ^/download/(.*)$ /files/$1 last;
}
location /files/ {
rewrite ^/files/(.*)$ /protected/$1 break;
}
这个例子展示了如何使用last和break标志进行多级重写。
注意事项 #
- 重写规则的顺序很重要,Nginx按照配置文件中的顺序处理规则
- 使用
last标志时,Nginx会重新开始搜索location块,可能导致循环 - 使用
break标志可以防止循环,但会停止所有重写规则的处理 - 在使用正则表达式时要小心,错误的表达式可能导致意外的行为
实际应用场景 #
- 网站迁移:将旧网站的URL结构重定向到新网站
- URL规范化:确保所有URL遵循一致的格式
- 隐藏真实路径:隐藏实际的文件路径,增强安全性
- 实现伪静态:将动态URL转换为静态URL格式