You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX Lua中Content-Length多1字节问题求助

问题根源与解决方案

这个问题我之前排查过,核心原因就在ngx.say这个OpenResty API的默认行为上!

为什么会多1字节?

ngx.say和ngx.print的关键区别是:ngx.say会自动在输出内容的末尾追加一个换行符(ASCII码为10,占1字节)。

你代码里的js_content长度是80字节,但执行ngx.say(js_content)后,实际输出的内容是js_content + \n,总字节数变成了81。这就导致:

  • 不设置Content-Length时,Nginx会自动计算实际输出的81字节,所以Firefox显示传输了81字节,能正常解析;
  • 手动设置Content-Length为80时,声明的长度和实际输出的字节数不匹配,VB.Net的JSON解析器就会因为数据不完整报错;而把长度设为81时,刚好匹配实际输出,所以能正常运行。

两种解决方法

方法1:替换ngx.say为ngx.print

如果你的JSON响应不需要末尾的换行符,直接用ngx.print输出,它不会额外添加任何字符:

local ref_array = {1, 2, 3}
local sArray = {}
sArray["1"] = "One"
sArray["2"] = "Two"
sArray["3"] = "Tree"
local ctable = {}
for index, data in ipairs(ref_array) do
    if sArray[tostring(data)] ~= nil then
        local cinfo = {}
        cinfo["X"] = tostring(data)
        cinfo["Y"] = sArray[tostring(data)]
        cinfo["Z"] = 0
        table.insert(ctable, cinfo)
    end
end
local js_content = cjson.encode(ctable)
ngx.header['Content-Type'] = 'application/json'
ngx.header['Content-Length'] = #js_content -- 现在和实际输出字节数完全一致
ngx.print(js_content) -- 用print代替say,不追加换行
ngx.exit(200)

方法2:保留ngx.say,调整Content-Length

如果因为某些原因必须用ngx.say,那就要把换行符的1字节算进Content-Length里:

-- 前面的代码完全不变
local js_content = cjson.encode(ctable)
ngx.header['Content-Type'] = 'application/json'
ngx.header['Content-Length'] = #js_content + 1 -- 加上换行符的1字节
ngx.say(js_content)
ngx.exit(200)

内容的提问来源于stack exchange,提问作者SweetNGX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:29:00