这个问题也可能是:"如何用RegEx修改NGiNX变量?",或者:"RegEx反向引用是否有间隙?"
这两个都能解决我的问题。也许有一个非常简单的解决方案,在浏览了几个小时之后,是时候寻求帮助了。
这是一个场景:
请求URI中有一部分将始终存在(对于一种噱头域名+URI组合:-)。我强制存在始终存在的URI路径组件,该组件紧跟在域名之后,如下所示:
http://somedomain.com/basepart/rest/of/the/path?q=123
在上面的示例中,"/basepart"表示始终存在的URI组件。
到目前为止还不错。当我希望基本文件路径为/var/www/somedomain.com/htdocs/
而不包含basepart
,并且使用php5_fpm代理时,就会出现问题。我显然设置了:
location /basepart {
alias /var/www/somedomain.com/htdocs;
try_files $uri $uri/ /index.php?$args;
}
但是由于动态文件是在PHP中的,所以我需要使用fastcgi_split_path_info
或$request_uri
来构建SCRIPT_FILENAME
/将其传递给php5_fpm。我该怎么做?如何从$fastcgi_script_name
或$request_uri
中删除/basepart
,否则PHP将在/var/www/somedomain.com/htdocs/basepart
中查找该文件?
我已经考虑过命名的backreferences,或者"收集"或"碎片化"的backreference(我认为regex中不存在这些),这样当fastcgi_split_path_info
赋值发生时,我就可以在$fastcgi_script_name
中的basepart之前和之后捕获段,但还没有使它们起作用Dayo早些时候在SO:»Nginx是一个Web服务器,而不是一个脚本应用程序。»,并建议使用Lua进行更复杂的脚本编写。但我有一种感觉,我可能忽略了一些非常简单、值得一试的解决方案:-]。
有什么想法吗?
如果其他人偶然发现了这个问题,经过头脑风暴,我想出了一个愚蠢而明显的解决方案:
root /app/frontend/web/;
location /api/ {
alias /app/backend/web/;
index index.php index.html;
# Double /api/ because "that's how nginx alias and try_files works together"
try_files $uri /api//api/index.php$is_args$args;
location ~ ^/api(/.*'.php(?:'?.*)?)$ {
try_files $uri /api//api/index.php$is_args$args;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
...
}
}
即使用正则表达式捕获组。
根据此规则,请求将按以下方式路由:
/index.html -> /app/frontend/web/index.html
/test/test.php -> /app/frontend/web/test/test.php as plaintext
/api/<somepath> -> /app/backend/web/<somepath> (proxied to FPM if .php) if it exists, otherwise /app/backend/web/index.php
alias
指令适用于静态网站,但在涉及PHP时就不那么有用了。我的首选解决方案是在不使用/basepart
的情况下内部重写URI,然后使用root
而不是alias
。
问题是,许多PHP脚本使用$request_uri
来处理请求,而/basepart
则被冻结。但是,我们可以指定为REQUEST_URI
选择的任何值,并从$uri
或捕获中构造更合适的值。在下面的例子中,我在第一次重写后保留了$uri
的值,这样它就可以用来将我们修改后的请求URI传递给PHP脚本。
root /var/www/somedomain.com/htdocs;
location ^~ /basepart {
rewrite ^/basepart/(.*)$ /$1 last;
rewrite ^ / last;
}
location / {
internal;
try_files $uri @index;
}
location @index {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param REQUEST_URI $uri;
...
}
location ~ '.php$ {
internal;
try_files $uri @index;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $uri;
...
}
fastcgi
代码块在两个位置上重复。如果它变得难以处理,则可以将通用代码放入一个单独的包含文件中。
通过使用internal
指令使位置成为私有位置,使/basepart
对于外部访问是强制性的。