摘自:http://www.daileinote.com/computer/openresty/07
内部子请求
子请求在内部执行,非常高效。子请求会缓冲所有的响应体,如果响应体很大,建议用 cosockets 来操作。
子请求默认情况下会继承所有父请求的请求头。
ngx.location.capture
1 | syntax: res = ngx.location.capture(uri, options?) |
基本用法
1 | res = ngx.location.capture(uri) |
res是一个表格,包含4个成员
res.status 子请求响应的状态码
res.header 表格的形式存放子请求的响应头,如果有同名多个响应头,那么值也为表格,比如假设响应头有3个 Set-Cookie。
1 | Set-Cookie: a=3 |
那么 res.header["Set-Cookie"] 里的值为
1 | {"a=3", "foo=bar", "baz=blah"} |
res.body 存放响应体内容,必须通过检查 res.truncated 返回值来确认响应体是否完整,如果为 true,那么证明响应体被裁剪过了不完整,可能是由于一些错误导致的。
查询的参数也可以结合到uri比如
1 | res = ngx.location.capture('/foo/bar?a=3&b=4') |
这里不支持命名 location 比如 @foo,如果想使用只允许内部子请求的location,可以在 location 块里加上 internal 指令。
第二个可选参数表格:
method 指定请求方法比如 ngx.HTTP_POST。
body 指定的请求体,只支持字符串。
args 指定查询字符串,支持表格。
ctx 指定子请求里的 ngx.ctx 表格,如果当前请求里传入 ngx.ctx ,那么可以实现父子请求共用上下文。
vars 表格形式指定传递给子请求的变量,在子请求可以用 ngx.var.name 获取。
copy_all_vars 布尔值,是否复制父级所有nginx变量到子请求,那么在子请求改变变量值不会影响到福请求。
share_all_vars 布尔值,是否共享当前所有变量到子请求。
always_forward_body 布尔值,是否总是发送当前请求体。如果开启,那么如果没有指定 body 参数,会把当前通过 ngx.req.read_body() 收到的请求体直接发送给子请求而无需拷贝请求体数据,不管请求体数据在内存里还是在临时文件里。默认为false,如果没有指定 body 参数,只有子请求方法为 PUT 或者 POST 时才放松当前请求体。
1 | --POST请求 |
共享参数可能会造成一些负面影响,最好用 args、vars、copy_all_vars 代替。
1 | location /other { |
如果同时指定,copy_all_vars 和 share_all_vars,那么 share_all_vars 优先级更高。
ctx 选项
1 | location /sub { |
当然也可以通过 ctx 选项来共享请求上下文。
1 | location /sub { |
ngx.location.capture_multi
同上,只是它支持多个子请求平行运行,按相同的顺序返回,所花费的时间为多个请求里时间最长的那个。
1 | res1, res2, res3 = ngx.location.capture_multi{ |
上面两个指令的关系类似于下面
1 | ngx.location.capture = |
内部重定向 - ngx.exec
1 | syntax: ngx.exec(uri, args?) |
执行内部重定向到 uri,并附加上 args 参数。
1 | ngx.exec('/some-location') |
通过表格的形式传递参数,类似于 ngx.encode_args 方法。
ngx.exec 支持命名 location,但是 args 参数将会被忽略,不过可以通过 uri 传递。
1 | location /foo { |
注意:重定向前必须没有任何输出,也就是必须在 ngx.send_headers 或者是 ngx.print、ngx.say之前调用。建议配合 return 来强调重定向后会终止请求。
外部重定向 - ngx.redirect
1 | syntax: ngx.redirect(uri, status?) |
支持的状态码有:301、302(默认)、303、307、308。
1 | return ngx.redirect("/foo") |
该重定向类似于 ngx_http_rewrite_module 里,rewrite 指令配合 redirect 修饰符。
1 | rewrite ^ /foo? redirect; #nginx 配置 |
等同于
1 | return ngx.redirect('/foo'); -- Lua code |
下面也等同
1 | rewrite ^ /foo? permanent; #nginx 配置 |
注意:重定向前必须没有任何输出,也就是必须在 ngx.send_headers 或者是 ngx.print、ngx.say之前调用。建议配合 return 来强调重定向后会终止请求。
1 | location /foo { |
