前言
nginx默认不读取请求体的数据,但可以通过$request_body
内置变量来获取。$request_body
存在内存中,如果它的字节大小超过nginx配置的client_body_buffer_size
的值,nginx就会把请求体存放到临时文件中。此时数据就不在内存中了,这会导致$request_body
为空。
同步非阻塞方式获取请求体
ngx.req.read_body
含义:同步读取客户端请求体,且不会阻塞nginx的事件循环。使用此指令后,就可以通过ngx.req.get_body_data
来获取请求体的数据了。但如果使用临时文件来存放请求体,就需要先使用函数ngx.req.get_body_file
来获取临时文件名,再读取临时文件中的请求体数据。
环境:rewrite_by_lua*
、access_by_lua*
、content_by_lua*
ngx.req.get_body_data
含义:执行ngx.req.read_body
指令后,可以使用本指令在内存中获取请求体数据,结果会返回一个lua的字符串类型的数据。如果要获取table类型的数据,则需要使用ngx.req.get_post_args
。
环境:rewrite_by_lua*
、access_by_lua*
、content_by_lua*
、log_by_lua*
ngx.req.get_post_args
含义:读取包含当前请求在内的所有post请求的查询参数,返回一个table类型的数据
环境:rewrite_by_lua*
、access_by_lua*
、content_by_lua*
、log_by_lua*
、header_filter_by_lua*
、body_filter_by_lua*
ngx.req.get_body_file
含义:获取存放请求体的临时文件名。如果请求体被存放在内存中,获取的值就是nil。
示例
获取string类型的请求体
location /testlua { client_max_body_size 10k; client_body_buffer_size 1k; content_by_lua_block { local ngx = require "ngx"; ngx.req.read_body() -- 开启读取请求体模式 local data = ngx.req.get_body_data() -- 获取内存中的请求体 if data then ngx.print(string.format("data: %s, type: %s",data,type(data))) return else local file = ngx.req.get_body_file() -- 如果内存中没有, 则到临时文件中读取 if file then ngx.say("body is in file ", file) else ngx.say("no body found") end end } }
请求测试
curl -i http://192.168.1.111/testlua -d 'test=123&a=qwe&b=zxc' HTTP/1.1 200 OK Server: openresty Date: Sun, 28 May 2023 10:05:51 GMT Content-Type: application/octet-stream Transfer-Encoding: chunked Connection: keep-alive data: test=123&a=qwe&b=zxc, type: string
获取table类型的请求体
location /testlua { client_max_body_size 10k; client_body_buffer_size 1k; content_by_lua_block { local ngx = require "ngx"; ngx.req.read_body() -- 开启读取请求体模式 local args, err = ngx.req.get_post_args() -- 获取内存中的请求体 if args then for k,v in pairs(args) do if type(v) == "table" then ngx.say(k, ": ", table.concat(v, ", ")) else ngx.say(k, ": ", v) end end else local file = ngx.req.get_body_file() -- 如果内存中没有, 则到临时文件中读取 if file then ngx.say("body is in file ", file) else ngx.say("no body found") end end } }
请求测试
curl -i http://192.168.1.111/testlua -d 'test=123&a=qwe&b=zxc' HTTP/1.1 200 OK Server: openresty Date: Sun, 28 May 2023 10:37:48 GMT Content-Type: application/octet-stream Transfer-Encoding: chunked Connection: keep-alive a: qwe b: zxc test: 123
参考
- 《Nginx实战:基于lua语言的配置、开发与架构详解》