使用js_body_filter njs指令时Nginx不返回响应体问题求助
问题原因
你的配置存在3个核心问题导致无法正常返回响应:
- 静态文件服务默认开启
sendfile,该特性会直接在内核态完成静态文件的网络发送,绕过用户态的过滤器链,你编写的njs body过滤器逻辑完全没有被执行。 - 你使用全局变量存储响应内容,多请求并发场景下会出现数据串扰。
- 原静态响应自带
Content-Length头,若你修改了响应内容长度或者使用chunked编码传输,会和原长度不匹配导致客户端等待超时。 - 你配置的
proxy_buffering off仅对反向代理场景生效,静态文件场景下无任何作用。
解决方案
对配置做如下修改即可恢复正常:
1. 修改default.conf的location块
location / { sendfile off; # 关闭sendfile,让静态内容经过过滤器链 js_header_filter envsubst.remove_content_length; # 新增头过滤器删除Content-Length js_body_filter envsubst.process; root /etc/nginx/www; index index.html index.htm; try_files $uri $uri/ /index.html; expires -1; }
2. 修改envsubst.js逻辑
function remove_content_length(r) { // 删除原Content-Length头,让nginx自动使用chunked编码传输 delete r.headersOut['Content-Length']; } function process(r, data, flags) { // 响应内容存储在请求对象上,避免全局变量串数据 if (!r.res) r.res = ""; r.res += data; if (flags.last) { // 所有chunk接收完成后发送处理后的完整内容 r.sendBuffer(r.res.toLowerCase(), flags); } else { // 非最后一个chunk时丢弃原始内容,避免nginx默认发送 r.sendBuffer("", flags); } } export default { remove_content_length, process };
修改后重新构建镜像运行即可,curl请求会正常返回处理后的响应内容。
内容的提问来源于stack exchange,提问作者lbednaszynski
相关产品推荐
相关产品推荐

