重定向与内部子请求
Nginx的rewrite指令不仅可以在Nginx内部的server、location之间进行跳转,还可以进行外部链接的重定向。通过ngx_lua模块的Lua函数除了能实现Nginx的rewrite指令的功能之外,还能顺利完成内部子请求、并发子请求等复杂功能。
实战案例运行准备:本节涉及的配置文件为源码工程的nginxlua-demo.conf文件。在运行本节实例前需要修改启动脚本openrestystart.bat(或openresty-start.sh)中的PROJECT_CONF变量的值,将其改为nginx-lua-demo.conf,然后重启OpenRestry。
Nginx Lua内部重定向
ngx_lua模块可以实现Nginx的rewrite指令类似的功能,该模块提供了两个对应的API来实现重定向的功能,主要有:
(1)ngx.exec(uri,args?):内部重定向。
(2)ngx.redirect(uri,status?):外部重定向。
首先看第一个ngx.exec(uri,args?)内部重定向方法,其等价于下面的rewrite指令:
rewrite regrex replacement last;
下面是3个使用ngx.exec进行重定向的例子。
第一个例子是一个不带参数的重定向:
#重定向到/internal/sum
ngx.exec('/internal/sum');
第二个例子是一个使用字符串作为追加参数的重定向:
#重定向到/internal/sum?a=3&b=5,并且追加参数c=6
ngx.exec('/internal/sum?a=3&b=5', 'c=6');
第三个例子是一个使用Lua table作为追加参数的重定向:#重定向到/internal/sum,并且追加参数 ?a=3&b=5&c=6
ngx.exec('/internal/sum', {a=3, b=5,c=6});
下面是一个完整的ngx.exec重定向的演示例子,通过内部重定向完成3个参数的累加,具体代码如下:
location /internal/sum {
internal; #只允许内部调用
content_by_lua_block {
--通过ngx.var访问Nginx变量
local arg_a = tonumber(ngx.var.arg_a);
local arg_b = tonumber(ngx.var.arg_b);
local arg_c = tonumber(ngx.var.arg_c);
--3个参数值求和
local sum = arg_a + arg_b+ arg_c;
--输出结果
ngx.say(arg_a, "+", arg_b, "+", arg_c, "=",sum);
}
}
location /sum {
content_by_lua_block {
-- local res = ngx.exec("/internal/sum", 'a = 100&b=10&c=1');
-- 内部重定向到/internal/sum
return ngx.exec("/internal/sum", {a = 100, b = 10, c = 1});
}
}
以上代码处于nginx-lua-demo.conf文件中,修改后需重启OpenRestry,然后可以使用浏览器访问/sum,具体的访问结果如图8-15所示。
图8-15 Nginx Lua内部重定向演示
ngx.exec的使用需要注意以下两点:
(1)如果有args参数,参数可以是字符串的形式,也可以是Luatable的形式,代码如下:
ngx.exec("/internal/sum",'a=100&b=5'); --参数是字符串的形式
ngx.exec("/internal/sum", {a=100, b=5}); --参数是Lua table的形式
(2)该方法可能不会主动返回,因此建议在调用该方法时显式加上return,代码如下:
return ngx.exec(...)
Nginx Lua外部重定向
ngx_lua模块的外部重定向方法为ngx.redirect,它的语法格式如下:
ngx.redirect(uri, status?)
ngx.redirect外部重定向方法与ngx.exec内部重定向方法不同,外部重定向将通过客户端进行二次跳转,所以ngx.redirect方法会产生额外的网络流量,该方法的第二个参数为响应状态码,可以传递301/302/303/307/308重定向状态码。其中,301、302是HTT