问题描述:恼人的双斜杠Bug
最近在配置网站Nginx伪静态规则时,遇到了一个典型问题:当用户访问不带www的域名时,会自动跳转到http://www.xxx.com//,URL末尾莫名其妙多了一个斜杠。
查看当时的Nginx配置规则:
nginx
if ($http_host !~ "^www\.(.*)"){
rewrite ^(.*)$ http://www.$http_host/$1 redirect;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php/$1 break;
}
表面看起来逻辑合理,但实际效果却不尽人意。
问题根源分析
经过仔细排查,发现问题出在变量使用不当上:
-
$http_host变量包含完整的域名(如xxx.com) -
当使用
http://www.$http_host/$1时:-
$http_host=xxx.com -
$1=/(请求的URI,根路径时为单个斜杠) -
结果:
http://www.xxx.com//← 出现双斜杠!
-
三种解决方案
方案一:简单修复法(快速解决)
nginx
if ($http_host !~ "^www\.") {
rewrite ^(.*)$ http://www.$http_host$1 redirect;
}
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php/$1 break;
}
改动点:去掉目标URL中的斜杠,直接拼接 $1
方案二:使用$host变量(推荐)
nginx
if ($http_host !~ "^www\.") {
rewrite ^(.*)$ http://www.$host$1 redirect;
}
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php/$1 break;
}
优势:$host 变量更可靠,会自动处理端口号等情况
方案三:最佳实践方案(强烈推荐)
nginx
# 统一域名(带www)
if ($host !~ "^www\.") {
return 301 $scheme://www.$host$request_uri;
}
# 路由重写
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php/$1 break;
}
为什么方案三是最佳选择?
1. 使用 return 301 替代 rewrite redirect
-
性能更好:
return指令直接返回,不进入重写阶段 -
语义更清晰:明确表示永久重定向(301)
2. 使用 $scheme 保持协议一致性
-
自动适应 HTTP/HTTPS 请求
-
用户访问
https://example.com会跳转到https://www.example.com
3. 使用 $request_uri 避免路径问题
-
$request_uri包含原始请求的完整URI(包括查询参数) -
完美解决双斜杠问题
4. 使用 $host 变量更安全
-
$host不包含端口号,避免重定向到非常用端口 -
在处理域名时更加稳定可靠
完整的最佳配置示例
nginx
server {
listen 80;
server_name example.com www.example.com;
# 强制HTTPS(如需)
# if ($scheme = http) {
# return 301 https://www.example.com$request_uri;
# }
# 统一域名格式
if ($host != 'www.example.com') {
return 301 $scheme://www.example.com$request_uri;
}
# 前端控制器模式
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP处理
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
验证配置并重载
修改配置后,务必验证语法并重载:
bash
# 检查配置文件语法 nginx -t # 重载Nginx配置 nginx -s reload
避坑总结
-
谨慎使用
$http_host:它可能包含端口号,导致意外结果 -
优先使用
return指令:性能优于rewrite的重定向 -
保持协议一致性:使用
$scheme变量 -
使用
$request_uri处理路径:避免双斜杠等路径问题 -
统一域名规范:选择带www或不带www的一种形式,并强制统一
这个看似简单的配置问题,实际上涉及到了Nginx变量特性、重定向机制等多个知识点。希望本文能帮助大家在配置伪静态时避开这个坑!
欢迎在评论区交流你在Nginx配置中遇到的其他问题!

1万+

被折叠的 条评论
为什么被折叠?



