Strange Nginx behavior with trailing slashes

只愿长相守 提交于 2021-02-10 18:51:54

问题


I've got a quite interesting behavior. I want to avoid trailing slashes in URL's on my site. I've put rewrite ^/(.*)/$ /$1 permanent; rule into my server block, so
https://example.com/something/,
https://example.com/something////
redirect to
https://example.com/something;
and
https://example.com/
redirects to
https://example.com

But https://example.com//// is redirected to ... https://enjoygifts.ru//// (actually don't redirected, it's 200 code). Why?

Here is my server block:


    server {
        listen 443 ssl;
        ...
        ... ssl directives
        ...

        root        /var/www/mysite.com;
        index       index.php;
        server_name mysite.com;
        rewrite ^/(.*)/$ /$1 permanent;

        location / {
            rewrite ^/.*$ /index.php last;
        }

        location ~ ^/index.php {
            try_files    $uri =404;
            include      /etc/nginx/fastcgi.conf;
            fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        }

        location ~ ^/storage/app/uploads/public { try_files $uri 404; }
        ...
        ... lot of similar location blocks
        ...
    }


回答1:


https://example.com doesn't really exist, the root URI is / - how it's displayed in the browser's address bar is browser dependent - some will automatically show the solitary / whereas others will remove a solitary /.

So you cannot redirect from https://example.com/ to https://example.com - it will be silently interpreted as a redirect from https://example.com/ to https://example.com/.

Nginx uses a normalized URI when evaluating location and rewrite statements, and generating the $uri variable. Multiple consecutive occurrences of / are folded into a single /.

Although the regular expression ^/(.*)/$ matches the URI //, the statement will never see it. Because Nginx has already normalised that URI to /, which does not match the regular expression.


If a root URI with multiple /s is a problem, apply a regular expression to the $request_uri variable, which contains the original URI before normalization and also includes the query string (if any).

For example:

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

This can be placed inside your location / {...} block. See this caution on the use of if.



来源:https://stackoverflow.com/questions/53168398/strange-nginx-behavior-with-trailing-slashes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!