简体   繁体   English

如何在 nginx 上从 /file.php 重定向到 /file?

[英]How redirect from /file.php to /file on nginx?

I'm currently hiding the .php extension from the urls on my nginx server with this configuration:我目前正在使用以下配置从我的 nginx 服务器上的 url 中隐藏 .php 扩展名:

location / {
    try_files $uri $uri/ @extensionless-php;
    index index.html index.htm index.php;
}

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

location @extensionless-php {
    rewrite ^(.*)$ $1.php last;
}

This is working perfectly, but how can I make nginx not allow adding the .php extension?.这是完美的工作,但我怎样才能让 nginx 不允许添加 .php 扩展名?。 In my example if you manually delete the .php it works but if you add it it remains permanent in the url.在我的示例中,如果您手动删除 .php,它可以工作,但如果您添加它,它将在 url 中保持永久状态。

To redirect those requests permanently with HTTP 301 code try要使用 HTTP 301 代码永久重定向这些请求,请尝试

rewrite ^(.*)\.php$ $1 permanent;

Put this directive before your location blocks.将此指令放在您的location块之前。

Update更新

After this being answered, OP asked another question (now being deleted) - what if you have the following webroot structure:在回答这个问题之后,OP 提出了另一个问题(现在被删除了)——如果你有以下 webroot 结构怎么办:

webroot
|
+-- index.php (PHP file)
|
+-- somename.php (PHP file)
|
+-- somename (folder)
|   |
|   +-- index.php (PHP file)
|
+-- someothername (folder)
    |
    +-- index.php (PHP file)

Previous solution makes it impossible to serve somename.php file, because the request to http://example.com/somename would be redirected by try_files directive to http://example.com/somename/ and in next turn would be served with somename/index.php file.以前的解决方案无法提供somename.php文件,因为对http://example.com/somename的请求会被try_files指令重定向到http://example.com/somename/然后接下来将提供somename/index.php文件。

This can be solved, but you'll have to stop using index and try_files directives and emulate their behavior with your own request processing logic.这可以解决,但您必须停止使用indextry_files指令并使用您自己的请求处理逻辑模拟它们的行为。 This is what I've ended up with:这就是我的结果:

map $original_uri $maybe_slash {
    ~/$      '';
    default  '/';
}

server {

    ...

    if ($original_uri = '') {
        set $original_uri $uri;
    }

    # redirect requests of '/somepath/somefile.php' to '/somepath/somefile'
    rewrite ^(.*)\.php$ $1 pemanent;

    location / {

        # this emulates 'try_files $uri $uri/ ...' directive behavior and redirects '/some/path'
        # to '/some/path/' if 'some/path.php' file does not exists, but 'some/path' folder exists
        # and there are 'some/path/index.html' file in that folder
        set $check_redirect $rewrited$maybe_slash;
        if ( $check_redirect = '1/' ) {
           return 301 $original_uri/$is_args$args;
        }

        if ( -f $document_root$uri.php ) { rewrite ^ $uri.php last; }

        # this emulates 'index index.php index.html' directive behavior
        if ( -f $document_root$uri${maybe_slash}index.php ) {
            set $rewrited 1;
            rewrite ^ $uri${maybe_slash}index.php last;
        }
        if ( -f $document_root$uri${maybe_slash}index.html ) {
            set $rewrited 1;
            rewrite ^ $uri${maybe_slash}index.html last;
        }

        # if a request for an absent resource should be served with some backend
        # controller, it is ok to use some 'try_files' directive here like
        # try_files $uri /index.php?path=$original_uri;

    }

    location ~ \.php$ {

        # this emulates 'try_files $uri $uri/ ...' directive behavior and redirects '/some/path'
        # to '/some/path/' if 'some/path.php' file does not exists, but 'some/path' folder exists
        # and there are 'some/path/index.php' file in that folder
        set $check_redirect $rewrited$maybe_slash;
        if ( $check_redirect = '1/' ) {
           return 301 $original_uri/$is_args$args;
        }

        # no 'try_files $uri =404'  or 'include snippets/fastcgi-php.conf' here, this location
        # can be reached only if requested PHP file is really exists in webroot folder
        include fastcgi.conf;
        fastcgi_param SCRIPT_FILENAME $document_root$uri;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;

    }

}

With this configuration and webroot structure given above使用上面给出的这种配置和 webroot 结构

  • request to http://example.com/ would be served with webroot/index.php file;http://example.com/请求将与webroot/index.php文件一起提供;
  • request to http://example.com/somename would be served with webroot/somename.php file;http://example.com/somename请求将与webroot/somename.php文件一起提供;
  • request to http://example.com/somename.php would be redirected to http://example.com/somename and served with webroot/somename.php file;http://example.com/somename.php请求将被重定向到http://example.com/somename并与webroot/somename.php文件一起提供;
  • request to http://example.com/somename/ would be served with webroot/somename/index.php file;http://example.com/somename/请求将与webroot/somename/index.php文件一起提供;
  • request to http://example.com/someothername would be redirected to http://example.com/someothername/ (since no webroot/someothername.php file exists) and served with webroot/someothername/index.php file.http://example.com/someothername请求将被重定向到http://example.com/someothername/ (因为不存在webroot/someothername.php文件)并与webroot/someothername/index.php文件一起提供。

Important note about custom HTTP error pages关于自定义 HTTP 错误页面的重要说明

If you have some custom error page, for example webroot/error/404.php for HTTP 404 error, instead of usual way to define it like如果您有一些自定义错误页面,例如webroot/error/404.php用于 HTTP 404 错误,而不是像通常那样定义它

error_page 404 /error/404.php;

you'd need to skip .php extension of that file:您需要跳过该文件的.php扩展名:

error_page 404 /error/404;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM