带有斜杠的奇怪 Nginx 行为

Posted

技术标签:

【中文标题】带有斜杠的奇怪 Nginx 行为【英文标题】:Strange Nginx behavior with trailing slashes 【发布时间】:2019-04-09 15:20:38 【问题描述】:

我有一个非常有趣的行为。我想避免在我的网站上的 URL 中使用斜杠。我已将 rewrite ^/(.*)/$ /$1 permanent; 规则放入我的服务器块中,所以 https://example.com/something/,https://example.com/something//// 重定向到 https://example.com/something; 和 https://example.com/ 重定向到 https://example.com

但是https://example.com////被重定向到...https://enjoygifts.ru////(实际上不重定向,是200码)。为什么?

这是我的服务器块:

服务器 听 443 ssl; ... ... ssl 指令 ... 根 /var/www/mysite.com; 索引 index.php; server_name mysite.com; 重写 ^/(.*)/$ /$1 永久; 地点 / 最后重写 ^/.*$ /index.php; 位置 ~ ^/index.php try_files $uri =404; 包括/etc/nginx/fastcgi.conf; fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; 位置 ~ ^/storage/app/uploads/public try_files $uri 404; ... ...很多类似的位置块 ...

【问题讨论】:

【参考方案1】:

https://example.com 并不真正存在,根 URI 是 / - 它在浏览器地址栏中的显示方式取决于浏览器 - 有些会自动显示单独的 /,而其他人会删除单独的 / .

因此您不能从https://example.com/ 重定向到https://example.com - 它会被默默地解释为从https://example.com/https://example.com/ 的重定向。

Nginx 在评估locationrewrite 语句并生成$uri 变量时使用normalized URI。多个连续出现的/ 被折叠成一个/

虽然正则表达式 ^/(.*)/$ 匹配 URI //,但语句永远不会看到它。因为 Nginx 已经将该 URI 规范化为 /,这与正则表达式不匹配。


如果具有多个 /s 的根 URI 存在问题,请将正则表达式应用于 $request_uri 变量,该变量包含规范化之前的原始 URI,还包括查询字符串(如果有)。

例如:

if ($request_uri ~ "^/2,(\?|$)")  
    return 301 /$is_args$args; 

这可以放在您的location / ... 块内。关于if的使用见this caution。

【讨论】:

感谢您的回复。好的,由于 Nginx 标准化和 ^/(.*)/$ 正则表达式,我们可以从 /something//// (/something//// -> /something/ -> /something) 获得 /something。但是如果^/(.*)/$ 看不到////,怎么可能从浏览器的地址栏中删除////

以上是关于带有斜杠的奇怪 Nginx 行为的主要内容,如果未能解决你的问题,请参考以下文章

带有 HTTPS 重定向的 Nginx 入口控制器尾部斜杠

带有斜杠的 Flask POST

Java:replaceAll 不适用于反斜杠?

firebase 存储:以斜杠结尾的奇怪文件名

python字符串格式中自动添加的反斜杠,pycharm

nginx 重写URL尾部斜杠