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
相关产品推荐
相关产品推荐

