Nginx 将查询字符串重写为路径参数
我有以下托管映像服务的nginx配置:Nginx 将查询字符串重写为路径参数,nginx,Nginx,我有以下托管映像服务的nginx配置: upstream thumbor { server localhost:8888; } server { listen 80; server_name my.imageserver.com; client_max_body_size 10M; rewrite_log on; location ~ /images {
upstream thumbor {
server localhost:8888;
}
server {
listen 80;
server_name my.imageserver.com;
client_max_body_size 10M;
rewrite_log on;
location ~ /images {
if ($arg_width="10"){
rewrite ^/images(/.*)$ /unsafe/$1 last;
}
rewrite ^/images(/.*)$ /unsafe/$1 last;
}
location ~ /unsafe {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://thumbor;
proxy_redirect off;
}
location = /favicon.ico {
return 204;
access_log off;
log_not_found off;
}
}
我正在尝试重写以下URL:
来自
至
这很容易,当我想允许查询字符串进入url路径时,问题就开始了,如下所示:
来自
至
如果查询字符串的顺序无关紧要,也会更好
我尝试使用:
$arg_宽度,但似乎不起作用
在ubuntu上使用nginx 1.6.1
非常感谢您的帮助。处理查询参数总是很困难的(Apache也是如此) 但在您的示例中,当您这样做时:
location ~ /images {
if ($arg_width="10"){
rewrite ^/images(/.*)$ /unsafe/$1 last;
}
rewrite ^/images(/.*)$ /unsafe/$1 last;
}
我看不出两次重写之间有什么区别。。。所以这可能就是它不起作用的原因
无论如何,您可以尝试类似的方法(基于):
您可以使用
arg_name
参数,并且可以去掉location
块:
rewrite ^/images/(.*)$ /unsafe/$1;
# WARNING: Here we suppose that when we have a "mode" parameter, we have
# width and height paremeters too
if ($arg_mode) {
rewrite ^/unsafe/(.*)$ /images/unsafe/smart/$arg_mode/${arg_width}x${arg_height}/$1 last;
}
您需要一个脚本选项来评估输入并构造重写URL。我使用第三方进行这种逻辑 在您的机器上安装或最好安装后,您需要将模块编译成Nginx 或者,您可以安装与几个模块捆绑在一起的Nginx,将Nginx完全转换为完整的web应用服务器。Openresty将在安装期间处理Lua/LuaJit依赖关系 如果您已经准备好了,这将为您完成以下工作:
upstream thumbor {
server localhost:8888;
}
server {
[...]
location ~ ^/images {
rewrite_by_lua '
-- Use local variables to limit their scope to this location block
local i, j, key, val, args, dimension, modetype, tempheight, replacement
-- We only go ahead if there are request arguments to start with
if ngx.var.is_args then
-- Get the request arguments
-- These are loaded into a Lua table of the form, { a = 1, b = 2, c = 3 }
args = ngx.req.get_uri_args()
-- Loop through the args table and build our replacement string
for key, val in pairs(args) do
if key == "width" then
if tempheight then
dimension = val .. "x" .. tempheight
else
dimension = val
end
elseif key == "height" then
if dimension then
dimension = dimension .. "x" .. val
else
tempheight = val
end
elseif key == "mode" then
modetype = val
end
end
-- Construct the replacement string.
replacement = "/unsafe/" .. dimension .. "/" .. modetype .. "/"
-- Replace "/images/" in the request url with the replacement string.
local newuri, n, err = ngx.re.sub(ngx.unescape_uri(ngx.var.request_uri), "/images/", replacement, "io")
-- If there is a new string, then redirect to the new URL
if newuri then
return ngx.redirect(newuri, 301)
end
end
';
}
location ~ /unsafe {
[...]
proxy_pass http://thumbor;
}
[...]
}
请展示你现在拥有的东西。我怀疑你没有逃过这个问号,但很难看出你的错误在哪里…这就是我目前所做的,我尝试了几种方法,包括$arg_width、$arg_height,但都不起作用。它不起作用,因为nginx显然不支持嵌套if,但当取消嵌套并稍微更改逻辑时,它工作得很好!谢谢你的帮助!是的,忘记了这个嵌套if限制。为了便于参考,您应该在修正中添加注释,或者用工作解决方案编辑此答案(或您的问题)。也许可以给@Dayo一部分奖励,因为LUA脚本也是一种避免危险操作的好方法,它使用
if
——就像Nginx中的“if是邪恶的”。
upstream thumbor {
server localhost:8888;
}
server {
[...]
location ~ ^/images {
rewrite_by_lua '
-- Use local variables to limit their scope to this location block
local i, j, key, val, args, dimension, modetype, tempheight, replacement
-- We only go ahead if there are request arguments to start with
if ngx.var.is_args then
-- Get the request arguments
-- These are loaded into a Lua table of the form, { a = 1, b = 2, c = 3 }
args = ngx.req.get_uri_args()
-- Loop through the args table and build our replacement string
for key, val in pairs(args) do
if key == "width" then
if tempheight then
dimension = val .. "x" .. tempheight
else
dimension = val
end
elseif key == "height" then
if dimension then
dimension = dimension .. "x" .. val
else
tempheight = val
end
elseif key == "mode" then
modetype = val
end
end
-- Construct the replacement string.
replacement = "/unsafe/" .. dimension .. "/" .. modetype .. "/"
-- Replace "/images/" in the request url with the replacement string.
local newuri, n, err = ngx.re.sub(ngx.unescape_uri(ngx.var.request_uri), "/images/", replacement, "io")
-- If there is a new string, then redirect to the new URL
if newuri then
return ngx.redirect(newuri, 301)
end
end
';
}
location ~ /unsafe {
[...]
proxy_pass http://thumbor;
}
[...]
}