【问题标题】:How redirect from /file.php to /file on nginx?如何在 nginx 上从 /file.php 重定向到 /file?
【发布时间】:2020-10-01 19:54:34
【问题描述】:

我目前正在使用此配置从我的 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;
}

这是完美的工作,但我怎样才能让 nginx 不允许添加 .php 扩展名?在我的示例中,如果您手动删除 .php 它可以工作,但如果您添加它,它将在 url 中保持永久状态。

【问题讨论】:

  • 对于那种类型的 URL,你希望 nginx 有什么行为? 301重定向,404未找到,还有什么?
  • @IvanShatsky 我希望如果用户尝试访问 file.php 自动 nginx 重定向到文件
  • 虽然您删除了第二个问题,但我看到了它并花了一些时间玩所有这些,请检查答案的更新。

标签: php ubuntu nginx seo


【解决方案1】:

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

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

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

更新

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

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 文件提供服务。

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

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 结构

  • 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 文件一起提供。

关于自定义 HTTP 错误页面的重要说明

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

error_page 404 /error/404.php;

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

error_page 404 /error/404;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 2011-04-23
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多