ZBLOG

openResty读取body_data

在 OpenResty(基于 Nginx + Lua)中读取 HTTP 请求的 body_data,可以使用 ngx.req.read_body()ngx.req.get_body_data()。以下是详细方法和注意事项:


1. 基础读取方法

  1. location /upload {
  2. content_by_lua_block {
  3. -- 必须先调用 read_body() 才能获取 body_data
  4. ngx.req.read_body()
  5. -- 获取请求体数据
  6. local body_data = ngx.req.get_body_data()
  7. if not body_data then
  8. ngx.say("Error: Failed to read request body")
  9. return ngx.exit(400)
  10. end
  11. -- 打印 body 内容(调试用)
  12. ngx.say("Body data: ", body_data)
  13. }
  14. }

2. 处理大文件(内存 vs 临时文件)

  • 默认情况:OpenResty 会将小请求体缓存在内存中,大文件会写入临时文件。

  • 强制全部读入内存

    1. -- nginx.conf http/server/location 中设置
    2. client_max_body_size 50m; --允许最大50MB请求体
    3. client_body_buffer_size 50m; --内存缓冲区大小设为50MB
  • 从临时文件中读取: 如果请求体超过 client_body_buffer_size,数据会被存入临时文件,需通过 ngx.req.get_body_file()获取路径:

  1. local temp_file = ngx.req.get_body_file()
  2. if temp_file then
  3. local file = io.open(temp_file, "rb")
  4. local body_data = file:read("*a")
  5. file:close()
  6. end

3. JSON/FormData解析示例

(1)解析 JSON Body:

  1. local cjson = require "cjson.safe"
  2. ngx.req.read_body()
  3. local json_str = ngx.req.get_body_data()
  4. local data = cjson.decode(json_str)
  5. if not data then
  6. ngx.say("Invalid JSON")
  7. return ngx.exit(400)
  8. end
  9. -- 使用 data.key1, data.key2...

(2)解析 Multipart FormData:

推荐使用第三方库如 lua-resty-upload

  1. local upload = require "resty.upload"
  2. local form = upload:new()
  3. while true do
  4. local typ, res, err = form:read()
  5. if not typ then break end
  6. if typ == "file" then
  7. -- res是文件名,err是文件内容块
  8. ngx.say("File chunk received")
  9. elseif typ == "form" then
  10. -- res是字段名,err是字段值
  11. ngx.say("Form field: ", res, "=", err)
  12. end
  13. end

4.常见问题排查

(1)返回 nil的可能原因:

  • ❌未调用 ngx.req.read_body()
  • ❌请求体超过 client_body_buffer_size且未处理临时文件
  • ❌客户端未正确发送数据(检查前端代码)

(2)性能优化建议:

  1. # nginx.conf优化项:
  2. http {
  3. lua_need_request_body on; #预读body到内存
  4. }

完整上传文件示例

  1. location /upload {
  2. client_max_body_size 100m;
  3. content_by_lua_block {
  4. local upload = require "resty.upload"
  5. --初始化上传处理器
  6. local form = upload:new()
  7. while true do
  8. local typ, res, err= form:read()
  9. if not typ then break end
  10. if typ=="file" and res=="file1" then
  11. local path="/tmp/"..err.filename
  12. local file=io.open(path,"wb")
  13. while true do
  14. local chunk=form:read()
  15. if not chunk or chunk==0 then break end
  16. file:write(chunk)
  17. end
  18. file:close()
  19. ngx.say("Saved:",path)
  20. end
  21. end
  22. }
  23. }

如果需要更具体的场景分析,可以提供以下信息:
1.你的Nginx/OpenResty版本 (nginx -V)
2.前端发送的具体代码片段


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23259

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?