为什么 Nginx 不会对以问号开头的 URL 返回 404 错误?

为什么 Nginx 不会对以问号开头的 URL 返回 404 错误?

我正在尝试让重写规则正常工作,但我发现如果 URL 以问号开头,Nginx 无法按预期返回 404 错误。相反,所有以“?”开头的 URL 都会使用 root 指令中定义的 index.html。(例如,example.com/?page-does-not-exist适用于主页,但不应该)

example.com/?format=feed&type=rss这使得从->重定向无法正常example.com/rss.xml工作。这是针对从 Joomla 迁移到 Jekyll 的博客。

简单来说,访问example.com/123 返回 404并参观example.com/?123 没有后者返回 URL example.com?/123 处的站点主页。(没有文件或文件夹“123”,因此对它的请求应该总是失败。)

网站的所有功能都运行正常,包括 HTTPS 重定向,但以问号开头的 URL 不会发生预期的 404 重定向。我该如何解决这个问题?

这是我的配置:

server {
    server_name example.com;
    root /var/www/example.com;
    index index.html;
    listen 443;
    ssl on;      
    ...

    rewrite "/?format=feed&type=rss" https://example.com/rss.xml permanent;

    location ~* \.(?:ico|css|js|gif|jpeg|jpg|png|txt|svg|eot|woff|ttf)$ {
            expires max;
            add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            add_header Access-Control-Allow-Origin *;
            valid_referers none blocked example.com;
            if ($invalid_referer) {
                    return 403;
            }
    }
}

# HTTP --> HTTPS
server {
        listen 80;
        server_name www.example.com example.com;
        return 301 https://example.com$request_uri;
}

答案1

问号表示 uri 路径部分的结束和查询字符串的开始。因此,nginx 不会根据问号后的部分返回 404;请求的资源确实存在,查询字符串参数只是传递给它。

关于问题的另一部分,我认为 nginx 的重写语句实际上并不与 uri 的查询字符串部分匹配。

然而你应该能够做类似的事情:

if ($args ~ "format=feed&type=rss") {
    rewrite ^ https://example.com/rss.xml? permanent;
}

答案2

NGinx将后面的所有内容解释?为查询字符串,而不是路径。

它只会对不存在的路径返回 404,而不会对查询字符串返回 404。

例如:

  • example.com/123:如果路径/123存在,并且该路径有索引文件,那么就可以了,否则将返回 404

  • example.com/?123:如果根目录中有一个索引文件,那么example.com就可以了。它不会检查目录是否?123存在,因为它不将其视为路径,而是视为查询字符串。

相关内容