【发布时间】:2017-01-03 10:37:55
【问题描述】:
我在搞乱 nginx 并试图将 mod_rewrite 规则转换为 nginx。到目前为止,我一直在使用以下内容:
RewriteEngine On
RewriteBase /
ErrorDocument 403 /HttpUnauthorized
ErrorDocument 404 /HttpNotFound
# Remove Trailing Slashes
RewriteCond %{REQUEST_METHOD} !=POST [NC]
RewriteCond %{REQUEST_URI} /$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^(.+)/$ $1 [NC,R=301,L]
# Removes index.php from URLs (actually this happens everywhere!)
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) $1$2 [R=301,NE,L]
# Directs all web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=/$1 [L,QSA]
我在网上找到的一个工具建议了以下输出:
error_page 404 /HttpNotFound;
error_page 403 /HttpUnauthorized;
location / {
if ($request_method != "POST") {
rewrite ^/(.+)/$ /$1 redirect;
}
rewrite (.*?)index\.php/*(.*) /$1$2 redirect;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?q=/$1 break;
}
}
而且(也许它也很重要)对于 PHP 我正在使用这个调用:
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_index index.php;
include fastcgi_params;
}
请求http://localhost/Foo 实际上是下载原始的index.php 源文件,但请求http://localhost/index.php?q=/Foo 会在浏览器中正确打开相应的站点并显示预期的输出。我的配置到底有什么问题?
尝试自定义规则后的一些问题
由于该工具的规则非常糟糕,我从一个基本的开始
location / {
try_files $uri $uri/ /index.php;
}
我以前通过$_REQUEST['q'] 获得的查询字符串现在可以使用$_SERVER['REQUEST_URI'] 读取。所以我尝试使用
rewrite ^/(.+)/$ /$1 permanent;
不幸的是,在我的特定设置中,这两种方法都有效,但不能同时有效。我在 Docker 容器中运行 nginx,因此服务器在内部侦听端口 80,同时暴露在端口 8082 上。由于 nginx 认为它在端口 80 上运行(即使我通过http://localhost:8082/Foo/ 请求)它重写为http://localhost/Foo .除了让服务器首先监听正确的端口之外,还有什么方法可以处理这个问题?
【问题讨论】:
-
我不确定是否能正确理解您对端口的评论。你的意思是重定向不再起作用了吗?或者 nginx 不知何故弄混了,认为查询实际上是针对另一个虚拟主机的?
-
@jwatkins 当我浏览到
http://localhost:8082/Foo/时,我希望被重定向到http://localhost:8082/Foo,但我被重定向到http://localhost/Foo/,这与http://localhost:80/Foo/相同。由于我在配置中有一个listen 80,这是因为服务器显然没有注意到我正在从 Docker 公开的另一个端口访问它。因此,我只是考虑在 PHP 本身中处理更困难的重写/重定向。 -
好的,这里有两点......首先,您不应该使用重定向来删除尾部斜杠。这会导致页面加载时间额外的完整往返损失,并且可以避免。其次,我记得通过添加额外的
listen 80xx语句解决了一个非常相似的问题;您不需要在 docker 容器上公开这些端口,但如果我没记错的话,nginx 会被此愚弄并停止尝试修复端口号。
标签: php apache .htaccess mod-rewrite nginx