应使用 access_by_lua_block 阶段配合 ngx.req.read_body() 读取并预处理请求体,完成校验、解密、字段注入等操作后通过 ngx.req.set_body_data() 替换,避免用 content_bylua* 或全局变量,大文件需流式处理。

要通过 location 块配置在 Nginx 中对特定 API 的请求体做预处理(比如修改、校验、解密、注入字段等),核心是利用 Lua 的 access_by_lua* 或 rewrite_by_lua* 阶段,在请求进入业务逻辑前完成操作,同时确保请求体已被读取。
确保请求体可被 Lua 读取
默认情况下,Nginx 不会主动读取 POST/PUT 等请求的 body,Lua 脚本调用 ngx.req.get_post_args() 或 ngx.req.get_body_data() 前必须先触发 body 读取。推荐两种方式:
- 在
location块中显式添加lua_need_request_body on;(简单直接,但官方不推荐用于高并发场景,因会阻塞) - 在 Lua 脚本开头调用
ngx.req.read_body()(更可控,建议使用)
选择合适的 Lua 执行阶段
预处理请求体通常属于访问控制或协议转换环节,应放在业务逻辑执行前:
-
access_by_lua_block或access_by_lua_file:最适合——它在权限检查、限流之后、content 处理之前运行,适合做参数校验、字段注入、body 解密等; -
rewrite_by_lua_block:也可用,但语义上更偏向 URI 重写或变量改写;若需根据 body 内容跳转或改写请求路径,可选此阶段; - 避免用
content_by_lua_*做预处理——此时响应已开始生成,再改 body 就晚了。
典型配置示例(预处理 /api/v1/order)
以下配置对 /api/v1/order 的 POST 请求进行 JSON body 校验与时间戳注入:
location = /api/v1/order {<br> lua_need_request_body on;<br> access_by_lua_block {<br> local args = ngx.req.get_post_args()<br> if not args or not args.order_id then<br> ngx.exit(400)<br> end<br> -- 注入当前时间戳到请求体(需重新构造)<br> local data = ngx.req.get_body_data()<br> if data then<br> local json = require "cjson"<br> local obj = json.decode(data)<br> obj.timestamp = ngx.time()<br> ngx.req.set_body_data(json.encode(obj))<br> end<br> }<br> proxy_pass http://backend;<br>}
注意事项与常见陷阱
- 修改请求体后,如使用
ngx.req.set_body_data(),需注意:原 body 已被丢弃,后续不能再调用get_post_args()(它依赖原始解析逻辑),应直接操作新 body 字符串; - 若需保留表单格式(application/x-www-form-urlencoded),预处理更复杂,建议统一走 JSON;
- 大 body(如文件上传)慎用内存式处理,可考虑流式解析或用
ngx.req.socket()边读边处理; - 所有 Lua 变量尽量用
local声明,避免污染全局环境; - 错误处理务必调用
ngx.exit()或ngx.log(),否则可能静默失败。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










