【问题标题】:nginx - rewriting index.php?hello=x to index/hello/xnginx - 将 index.php?hello=x 重写为 index/hello/x
【发布时间】:2011-10-12 19:34:14
【问题描述】:

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

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

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

我确信所有这些都已经在某个地方进行了介绍,但我无法理解 nginx 网站上的重写。

【问题讨论】:

    标签: nginx


    【解决方案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;
    }
    

    ... 将为每个“索引/问题/x”请求返回 404 错误。这是因为重写机制只是网络服务器对重写的资源发出后台请求的一种情况。

    所以“index/question/x”会生成一个“index.php?question=x”后台请求,该请求会点击该位置,说明应该返回“404”错误。

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      这应该将 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 确保这不会最终导致重写图像请求等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-18
        • 2022-08-19
        • 2012-10-06
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        • 2018-08-27
        相关资源
        最近更新 更多