使用APISIX插件改写响应时出现乱码非ASCII字符问题
APISIX数据脱敏插件响应乱码问题
我正尝试用Lua为APISIX开发一款数据脱敏插件,参考官方资料编写了自定义插件,也试过官方的response-rewrite插件,但两种方式都得到完全乱码的响应。预期响应是JSON格式:
{ "success": {}, "timeStamp": "2023-12-01 10:03:12.0", "version": "21.2.0.0" }
自定义插件的body_filter代码如下:
function _M.body_filter(conf, ctx) if conf.filters then local body = core.response.hold_body_chunk(ctx) if not body then return end local err for _, filter in ipairs(conf.filters) do body, _, err = re_gsub(body, filter.regex, filter.replace, "jo") if err ~= nil then core.log.error("regex \"" .. filter.regex .. "\" substitutes failed:" .. err) end end ngx.arg[1] = body return end end
我尝试在代码里打印获取到的响应体日志,结果日志里也是随机非ASCII字符,说明问题出在获取响应体的环节,而非替换逻辑。
问题原因及解决办法
核心原因:上游响应启用了gzip压缩
如果上游服务返回的响应是gzip压缩后的二进制数据,直接通过core.response.hold_body_chunk获取的话就是乱码,因为没有做解压处理。
解决步骤:
禁用上游响应的gzip压缩
在APISIX的路由配置中,给upstream添加headers配置,强制上游返回未压缩的内容:upstream: headers: set: Accept-Encoding: "identity"配置后上游会返回未压缩的文本响应,再进行脱敏处理就不会出现乱码。
在插件中手动解压响应体
如果无法修改上游配置,需要在插件中对压缩的响应体进行解压:local zlib = require "zlib" function _M.body_filter(conf, ctx) if conf.filters then local body = core.response.hold_body_chunk(ctx) if not body then return end -- 检查响应头中的压缩标识 local content_encoding = core.response.get_header(ctx, "Content-Encoding") if content_encoding and content_encoding == "gzip" then -- 初始化gzip解压流 local inflate, err = zlib.inflate() if not inflate then core.log.error("failed to create inflate stream: ", err) return end -- 执行解压 local decompressed_body = inflate(body) if err then core.log.error("failed to decompress body: ", err) return end body = decompressed_body -- 移除压缩标识头,避免下游收到错误的响应格式 core.response.set_header(ctx, "Content-Encoding", nil) -- 更新响应长度头,避免长度不匹配 core.response.set_header(ctx, "Content-Length", #body) end local err for _, filter in ipairs(conf.filters) do body, _, err = re_gsub(body, filter.regex, filter.replace, "jo") if err ~= nil then core.log.error("regex \"" .. filter.regex .. "\" substitutes failed:" .. err) end end ngx.arg[1] = body return end end注意:需要确保APISIX已安装
lua-zlib依赖,可通过opm install api7/lua-zlib完成安装。官方插件的正确配置
如果使用response-rewrite插件,同样需要确保上游响应未压缩,或者在插件配置中启用解压处理(部分版本支持),同时正确配置替换规则。
内容的提问来源于stack exchange,提问作者sarthak behki
相关产品推荐
相关产品推荐

