nginx - 将index.php?hello = x重写为index / hello / x

时间:2011-10-12 19:34:15

标签: nginx

如何使用nginx将index.php?question = x重写为index / question / x

make index.php?question = x返回404未找到(如果可能)

从网址中完全删除.php文件扩展名

我确信所有这些都已在某处覆盖,但我无法理解nginx网站上的重写。

2 个答案:

答案 0 :(得分:1)

如果index.php确实存在并且您想要重写它,则无法使index.php返回404错误。

这两个......

rewrite ^index/question/(.*)$ /index.php?question=$1 last;

location = /index.php {
    return 404;
}

......而这......

rewrite ^(.*)/(.*)/(.*)$ /$1.php?$2=$3 last;

location ~* \.php$ {
    return 404;
}

...将为每个“index / question / x”请求返回404错误。这是因为重写机制只是Web服务器发出重写资源的后台请求的情况。

因此“index / question / x”将生成一个“index.php?question = x”后台请求,该请求将触及该位置,表示应返回“404”错误。

如果你想从你的网址中完全摆脱index.php,你需要让你的应用程序停止生成index.php链接。如果您没有创建此类链接,它们将会停止使用。

你可以在Nginx和你的应用程序之间做一些事情来加快这个过程。

  1. 首先,将您的应用程序更改为始终生成“index / question / x”链接
  2. 在Nginx中为“/index.php?question=x”重写添加一个虚拟标记,以便您的应用程序知道这是来自Nginx的后台请求。
  3. 设置您的应用程序以测试是否存在此虚拟标记,以查找它获得的任何“/index.php?question=x”类型请求。如果存在,则提供请求,如果不存在,则重定向到“index / question / x”url。
  4. 我们还需要Nginx中的虚拟密钥(“apptag”)来识别这些类型的链接,这样我们就可以在自己的位置处理这些链接,而不会让我们的重写陷入其他合法链接。
  5. 在Nignx:

    # Any request uri starting with "/app_tag/" is given the treatment
    location ~* ^/app_tag/ {
        rewrite ^/app_tag/(.+)/(.+)/(.+)$ /$1.php?$2=$3&dummy_tag last;
        rewrite ^/app_tag/(.+)/?$ /$1.php?dummy_tag last;
    }
    location ~* \.php$ {
        #proxy_pass/fastcgi_pass etc
    }
    

    在您的申请中:

    $dummy_tag = "dummy_tag";
    $app_tag = "app_tag";
    $test_dummy_tag = preg_match($dummy_tag, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
    if (!$test_dummy_base_tag) {
        // Dummy tag not present so we need redirect user
        $pattern_all = '~^/(.+)\.php\?(.+)=(.+)~si';
        $test_pattern_all = preg_match($pattern_all, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
        if ($test_pattern_all) {
            preg_match($pattern_all, $_SERVER['REQUEST_URI'], $matches);
            $pattern_new = "/apptag/" . $matches[1] . "/" . $matches[2] . "/" . $matches[3] . "/";
        } else {
            $pattern = '~^/(.+)\.php$~si';
            $test_pattern = preg_match($pattern, $_SERVER['REQUEST_URI']) ? TRUE : FALSE;
            if ($test_pattern) {
                preg_match($pattern, $_SERVER['REQUEST_URI'], $matches);
                $pattern_new = "/" . $app_tag . "/" . $matches[1] . "/";
            }
        }
        header('HTTP/1.1 301 Moved Permanently');
        header (location: "http://" . $_SERVER['HTTP_HOST'] . $pattern_new);
    }
    

    您可以根据需要修改/扩展它。

答案 1 :(得分:0)

这应该将index / question / X重写为index.php?question = X并为index.php返回404 但是,无法保证删除.php

rewrite ^index/question/(.*)$ /index.php?question=$1 last;

location = /index.php {
  return 404;
}

您还可以尝试更通用的解决方案,例如

rewrite ^(.*)/(.*)/(.*)$ /$1.php?$2=$3 last;

location ~* \.php$ {
  return 404;
}

这会将A / B / C重定向到A.php?B = C. 并以.php

结尾的任何内容返回404

注意:你可能也希望将重写包装在一个位置块中,并使用try_files来确保这不会最终重写对图像的请求等。