![Nginx 查询字符串重写](https://linux22.com/image/775208/Nginx%20%E6%9F%A5%E8%AF%A2%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8D%E5%86%99.png)
我有如下配置,但出现 500 错误。这个错误可能出在哪里?
upstream masterservers {server 192.168.1.1:8000;}
upstream slaveservers {server 192.168.1.2:8001;}
map $request_uri $redirect_to {
"target=master" masterservers;
"target=slave" slaveservers;
}
server {
listen 80;
server_name 192.168.1.10;
location / {
proxy_pass http://$redirect_to;
}
}
当我调用以下 URL 时,出现以下错误。
http://192.168.1.10/app/index.html?target=master
http://192.168.1.10/app/index.html?target=slave
Nginx 日志:*2 invalid URL prefix in "http://", client: 192.168.1.11, server: 192.168.1.10, request: "GET /favicon.ico HTTP/1.1", host: "192.168.1.10", referrer: "http://192.168.1.10/app/index.html?target=master"
答案1
您正在将(从您的示例中$request_uri
等于 )与和字符串进行比较。没有匹配项,因此变量变为空字符串。如果您想检查 是否包含或子字符串,您可以在块内使用正则表达式模式:/app/index.html?target=master
target=master
target=slave
$redirect_to
$request_uri
target=master
target=slave
map
map $request_uri $redirect_to {
"~target=master" masterservers;
"~target=slave" slaveservers;
}
或者更好地检查$arg_target
变量值:
map $arg_target $redirect_to {
master masterservers;
slave slaveservers;
}
当请求中未指定查询参数(或其值无效)时,还请考虑使用某些default
值:target
map $arg_target $redirect_to {
master masterservers;
slave slaveservers;
default masterservers;
}
最后一个可以简化为
map $arg_target $redirect_to {
slave slaveservers;
default masterservers;
}
或者做一些初步检查,例如
map $arg_target $redirect_to {
master masterservers;
slave slaveservers;
}
server {
listen 80;
server_name 192.168.1.10;
if ($redirect_to = '') {
return 501; # HTTP 501 Not Implemented
}
location / {
proxy_pass http://$redirect_to;
}
}
更新
如果我正确理解了您的附加问题 - 如何从与主 HTML 文件相同的上游加载所有资产 - 您可以尝试使用两个链式块从 HTTPReferer
标头值中获取上游名称(如果查询参数不存在):target
map
map $arg_target $redirect_to {
master masterservers;
slave slaveservers;
default $by_referer;
}
map $http_referer $by_referer {
"~target=master" masterservers;
"~target=slave" slaveservers;
}
server {
...
}