【发布时间】:2011-10-12 19:34:14
【问题描述】:
如何使用 nginx 将 index.php?question=x 重写为 index/question/x
和
使 index.php?question=x 返回 404 未找到(如果可能)
和
从 URL 中完全删除 .php 文件扩展名
我确信所有这些都已经在某个地方进行了介绍,但我无法理解 nginx 网站上的重写。
【问题讨论】:
标签: nginx
如何使用 nginx 将 index.php?question=x 重写为 index/question/x
和
使 index.php?question=x 返回 404 未找到(如果可能)
和
从 URL 中完全删除 .php 文件扩展名
我确信所有这些都已经在某个地方进行了介绍,但我无法理解 nginx 网站上的重写。
【问题讨论】:
标签: nginx
如果 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 和你的应用程序之间做一些事情来加快这个过程。
在 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);
}
您可以根据需要修改/扩展它。
【讨论】:
这应该将 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 确保这不会最终导致重写图像请求等。
【讨论】: