前言

在之前的文章博客服务器迁移过程中介绍了 footprint 打造旅行地图,然后使用 Nginx 反向代理,将 ff.cn/travel 指向 127.0.0.1:886,原本访问一切正常,但是昨天碰到了一个新的问题:css/js/png 等文件请求 301 重定向过多,花了蛮久才解决问题,所以记下来提醒自己。

复现

在网站 /travel/ 目录下创建 hello.js 文件,请求 ff.cn/travel/hello.js,显示 ff.cn 将您重定向的次数过多

在开发者模式下查看网络请求,发现服务器将 ff.cn/travel/hello.js 重定向给自身,导致出现死循环。

解决

  1. 清除 cookie (无效)

当相应网页尝试对您进行重定向的次数过多时,您就会看到这条错误消息。
有时,网页打不开是因为 Cookie 出问题了。要修正该错误,请尝试清除 Cookie。

  1. 刷新 DNS / 更换 DNS (无效)

重定向过多可能发生了 DNS 劫持,可以刷新 DNS 或者换一个 DNS 地址。

  1. SSL 证书问题 (无效)

如果开启了强制访问 HTTPS 或者 SSL 证书更换,可能导致前后端接口不一致,陷入反复跳转,造成重定向过多,可以重置 SSL 证书或者重启强制访问 HTTPS。

分析

查看 Nginx 日志,发现浏览器发出请求 ff.cn/travel/hello.js 时,本应该转给 127.0.0.1:886/hello.js,然而日志中显示回应请求的链接是 127.0.0.1:80/travel/hello.js,怀疑是代理设置出现问题。
查看 ff.cn 的配置文件如下:

configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
server
{
listen 80;
listen 443 ssl http2;
server_name ff.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /ff.cn;

#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}

#SSL-END

#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END

#PHP-INFO-START PHP引用配置,可以注释或修改
#清理缓存规则

location ~ /purge(/.*) {
proxy_cache_purge cache_one $host$1$is_args$args;
#access_log /www/wwwlogs/ff.cn_purge_cache.log;
}
#引用反向代理规则,注释后配置的反向代理将无效
include /www/server/panel/vhost/nginx/proxy/ff.cn/*.conf;

include enable-php-00.conf;
#PHP-INFO-END

#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/ff.cn.conf;
#REWRITE-END

#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}

#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}

access_log /www/wwwlogs/ff.cn.log;
error_log /www/wwwlogs/ff.cn.error.log;
}
configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#PROXY-START/travel/
location ~* \.(php|jsp|js|css|png|cgi|asp|aspx)$
{
proxy_pass http://127.0.0.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
}
location /travel/
{
proxy_pass http://127.0.0.1:886/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;

add_header X-Cache $upstream_cache_status;

#Set Nginx Cache
add_header Cache-Control no-cache;
}
#PROXY-END/travel/

可以发现,问题出现在了代理配置中的 location ~* \.(php|jsp|js|css|png|cgi|asp|aspx)$ 这一块。当接受到 ff.cn/travel/hello.js 请求时,根据代理配置进行转发,js/css/png 等文件匹配上了第一条规则,于是请求被发往 127.0.0.1:80/travel/hello.js,也就刚好是 ff.cn/travel/hello.js 自身,造成了死循环。将这一片段或者 js|css|png 删除即可解决

后记

宝塔确实有点诡异,上一秒还好好访问的,结果突然就重定向了。以后碰到问题多看日志,更容易发现问题所在的地方。