![为什么我的 Nginx 位置规则没有优先?](https://linux22.com/image/645629/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%20Nginx%20%E4%BD%8D%E7%BD%AE%E8%A7%84%E5%88%99%E6%B2%A1%E6%9C%89%E4%BC%98%E5%85%88%EF%BC%9F.png)
我的网站的根文件夹中有一个 PHP 应用程序(Wordpress),并且对该网站的所有请求都可以顺利通过它运行。
但是,我有一个子文件夹 _links,我想用它来执行另一个不同的 php 脚本。
例如,如果用户访问 site.com/_links/221312,则 /_links 的 index.php 脚本将接管。
我以前使用 .htaccess 文件来实现这一点,但自从转移到 nginx 后,我就无法让它工作了。
这是旧的.htaccess 文件。
RewriteEngine On
RewriteRule ^([0-9]+)/?$ index.php?linkid=$1 [NC,L]
显然,我将 URL 的最后一部分作为参数传递给脚本。
这是我的 nginx 配置。对 site.com/_links/23423 等的请求被拾取if (!-e $request_filename)
并重写,/index.php?q=/_links/23423
而不是被位置块拾取。
server {
listen 127.0.0.1:8080;
server_name site.com www.site.com m.site.com;
root /var/www/site;
location ^~ /_links/ {
add_header location 1;
root /var/www/site/_links;
rewrite "^([0-9]+)/?$" /index.php?linkid=$1 break;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
index index.php index.html;
if (!-e $request_filename)
{
rewrite ^(.+)$ /index.php?q=$1 last;
}
location / {
try_files $uri $uri/ =404;
}
# pass the PHP scripts to FastCGI server listening on the php-fpm socket
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
access_log /var/log/nginx/site.com.access.log;
error_log /var/log/nginx/site.com.error.log notice;
}
我真的很困惑。这是怎么回事?
答案1
可能是因为^~
位置块上的前缀匹配()和nginx 正在跳过正则表达式检查:
如果最长匹配前缀位置有“^~”修饰符,则不检查正则表达式
尝试删除前缀检查,即:
location /_links/ {
Regex here
}
还消除这根声明你location /_links/ block
不需要它,看看nginx 陷阱欲了解更多信息,基本上root declaration
使用服务器然后匹配位置$root/$location
另外,如上所述,请查看try_files
指令,而不是if(condition){match}
即而不是:
if (!-f $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
更好的解决方案是:
try_files $uri $uri/ /index.php?q=$uri;
这也提到了nginx 陷阱 wiki 页面。
答案2
如果可能的话,避免使用嵌套位置。将 重写location ^~ /_links/
为location ^~ /_links/.*\.php
,我希望这就是您所需要的。如果您只使用一个位置来放置 *.php,效果会更好,可能将一些重写移到那里。