如何在 nginx 上从/file.php 重定向到/file? [英] How redirect from /file.php to /file on nginx?

查看:60
本文介绍了如何在 nginx 上从/file.php 重定向到/file?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用此配置从我的 nginx 服务器上的 url 中隐藏 .php 扩展名:

I'm currently hiding the .php extension from the urls on my nginx server with this configuration:

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;
}

这工作得很好,但是如何让 nginx 不允许添加 .php 扩展名?.在我的示例中,如果您手动删除 .php,它会起作用,但如果您添加它,它会在 url 中保持永久状态.

This is working perfectly, but how can I make nginx not allow adding the .php extension?. In my example if you manually delete the .php it works but if you add it it remains permanent in the url.

推荐答案

要使用 HTTP 301 代码永久重定向这些请求,请尝试

To redirect those requests permanently with HTTP 301 code try

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

将此指令放在您的 location 块之前.

Put this directive before your location blocks.

更新

在回答这个问题后,OP 提出了另一个问题(现在被删除了)——如果你有以下 webroot 结构怎么办:

After this being answered, OP asked another question (now being deleted) - what if you have the following webroot structure:

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

以前的解决方案无法提供 somename.php 文件,因为对 http://example.com/somename 的请求将被 try_files 重定向 指令到 http://example.com/somename/,接下来将与 somename/index.php 文件一起提供.

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.

这可以解决,但您必须停止使用 indextry_files 指令并使用您自己的请求处理逻辑模拟它们的行为.这就是我最终的结果:

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. 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;

    }

}

有了上面给出的这个配置和 webroot 结构

With this configuration and webroot structure given above

  • http://example.com/ 的请求将通过 webroot/index.php 文件提供;
  • http://example.com/somename 的请求将通过 webroot/somename.php 文件提供;
  • http://example.com/somename.php 的请求将被重定向到 http://example.com/somename 并与 webroot 一起提供/somename.php 文件;
  • http://example.com/somename/ 的请求将与 webroot/somename/index.php 文件一起提供;
  • http://example.com/someothername 的请求将被重定向到 http://example.com/someothername/(因为没有 webroot/someothername.php 文件存在)并与 webroot/someothername/index.php 文件一起提供.
  • request to http://example.com/ would be served with webroot/index.php file;
  • request to http://example.com/somename would be served with webroot/somename.php file;
  • request to http://example.com/somename.php would be redirected to http://example.com/somename and served with webroot/somename.php file;
  • request to http://example.com/somename/ would be served with webroot/somename/index.php file;
  • 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 错误页面的重要说明

如果您有一些自定义错误页面,例如 webroot/error/404.php 用于 HTTP 404 错误,而不是像通常那样定义它

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

error_page 404 /error/404.php;

您需要跳过该文件的 .php 扩展名:

you'd need to skip .php extension of that file:

error_page 404 /error/404;

这篇关于如何在 nginx 上从/file.php 重定向到/file?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆