Node.js调用fetch()报错:net::ERR_INVALID_CHUNKED_ENCODING
问题
我尝试让客户端发送fetch请求,让本地部署的服务器返回消息“hello from server”。以下是我的代码:
服务端代码
const http = require('http') const fs = require('fs') const server = http.createServer((req,res) => { handleRequest(req,res).then(e => { if(e){ //处理非静态文件请求 if(e.req.url == '/test'){ e.res.writeHead(200) e.res.write('hello from server') }else{ e.res.writeHead(404) } e.res.end() } }) }) server.listen(3000) function handleRequest(req,res){ return new Promise(resolve => { //此处省略静态文件处理代码 //若非静态文件请求则resolve({req: req, res: res}) //否则resolve(null)并返回文件 })
客户端代码
const btn = document.getElementById('btn') const messageFromServerHeader = document.getElementById('message-from-server-header') btn.onclick = () => { fetch('/test').then(res => { console.log(res) }) }
运行代码点击按钮后,Chrome中报错:
GET http://localhost:3000/test net::ERR_INVALID_CHUNKED_ENCODING 200 (OK)
Firefox中报错:
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
服务器可正常提供静态文件,但处理fetch请求时出现异常。我查阅资料后推测可能与“Transfer-Encoding: chunked”响应头有关,但不确定是否为此问题,也不知如何修改。另外,服务端响应头中chunkEncoding为false,但Chrome网络面板显示transfer-encoding为chunked。请问问题出在哪里?
解决方案
问题根源在于:当前响应处理逻辑未正确设置响应头,导致Node.js自动启用的chunked编码出现异常,或者handleRequest里的静态文件处理逻辑对res对象造成了残留影响。
直接给出两种可行的修改方案:
方案一:明确设置Content-Length头
处理/test请求时,手动指定响应内容的长度,避免Node自动使用chunked编码:
if(e.req.url == '/test'){ const responseText = 'hello from server' e.res.writeHead(200, { 'Content-Length': Buffer.byteLength(responseText), 'Content-Type': 'text/plain' // 建议同时指定内容类型,避免浏览器解析异常 }) e.res.write(responseText) }
方案二:用res.end直接发送内容
简化响应逻辑,直接通过res.end()发送内容,Node会自动处理好响应头和编码问题:
if(e.req.url == '/test'){ e.res.writeHead(200, {'Content-Type': 'text/plain'}) e.res.end('hello from server') // 替代write+end的组合,让Node自动处理编码细节 }
补充说明
- 分开调用
res.write()和res.end()却未设置Content-Length时,Node会默认用chunked编码传输。如果静态文件处理逻辑中已经修改过res的状态(比如写入了部分响应头但未完成),就会导致分块编码格式错误,触发浏览器报错。 - 用
res.end()直接发送内容时,Node会自动计算内容长度并设置Content-Length,或者在需要时正确处理chunked编码,从根源避免无效编码的问题。
内容的提问来源于stack exchange,提问作者BigChungus443
相关产品推荐
相关产品推荐

