这个问题也可能是:“如何使用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。我怎么做?如何从/basepart
或$fastcgi_script_name
删除$request_uri
,否则PHP会在/var/www/somedomain.com/htdocs/basepart
中查找该文件?
我考虑过命名反向引用,或“收集”或“碎片化”反向引用(我认为它不存在于正则表达式中),以便我可以在$fastcgi_script_name
之前和之后捕获fastcgi_split_path_info
中的段{ {1}}分配发生了,但没有让它们起作用。 Dayo writes earlier at SO:»Nginx是一个网络服务器而不是脚本应用程序。»,并建议使用Lua进行更复杂的脚本编写。但我有一种感觉,我可能会忽略一些非常简单,有价值的解决方案: - ]。
任何想法,任何人?
答案 0 :(得分:2)
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
必须进行外部访问。
答案 1 :(得分:0)
如果有人偶然发现了这个问题,经过一番集思广益,我想出了一个显而易见的解决方案:
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