如何让 Nginx 将所有不存在的文件请求重定向到单个 php 文件?

如何让 Nginx 将所有不存在的文件请求重定向到单个 php 文件?

我有以下 nginx vhost 配置:

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    try_files $uri /index.php;

    location ~ \.php$ {
            if (!-f $request_filename) {
                    return 404;
            }

            fastcgi_pass localhost:9000;
            fastcgi_param SCRIPT_FILENAME /path/to/site/dir/webroot$fastcgi_script_name;
            include /path/to/nginx/conf/fastcgi_params;
    }
}

我想将所有与现有文件不匹配的请求重定向到 index.php。目前,这对大多数 URI 都适用,例如:

example.com/asd
example.com/asd/123/1.txt

asd或都不asd/123/1.txt存在,所以它们被重定向到 index.php,并且工作正常。但是,如果我输入 url example.com/asd.php,它会尝试查找asd.php,如果找不到,它会返回 404,而不是将请求发送到index.php

如果不存在的话,有没有办法asd.php也可以发送到?index.phpasd.php

答案1

根据您的补充评论,这听起来可能是最优的方式,尽管它不是一个很好的配置。

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri @missing;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /path/to/nginx/conf/fastcgi_params;
    }

    location @missing {
        rewrite ^ /error/404 break;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        include /path/to/nginx/conf/fastcgi_params;
    }
}

答案2

哇,我认为您想要替换的代码是:

error_page 404 /index.php

...如果我正确理解了你的意思。

答案3

您尝试执行的操作与自定义错误页面相同。您可以使用 nginx 的 error_page 属性来实现此目的。点击链接获取更多信息

http://wiki.nginx.org/HttpCoreModule#error_page

答案4

我认为问题在于您在位置中使用了“try_files”和“if”语句。根据文档,try_files 应该是 if 和 mod_rewrite 样式存在性检查的替代品。从 nginx wiki 来看,“try_files”页面 (http://wiki.nginx.org/HttpCoreModule#try_files):

“try_files 基本上是典型的 mod_rewrite 样式文件/目录存在性检查的替代品。它被认为比使用 if 更有效 - 请参阅 IfIsEvil”

查看“if”维基页面(http://wiki.nginx.org/NginxHttpRewriteModule#if):

“注意:在使用 if 之前,请参阅 if 是邪恶的页面,并考虑使用 try_files。”

因此,尝试删除该 if 检查,只保留“try_files”。它应该检查是否存在任何页面(包括 asd.php 或以 .php 结尾的其他任何内容),如果找不到,则返回 index.php。

相关内容