res.writeHead与res.end分属不同作用域引发ERR_STREAM_WRITE_AFTER_END错误
解析 Node.js 中
ERR_STREAM_WRITE_AFTER_END 错误的根源 你遇到的这个ERR_STREAM_WRITE_AFTER_END错误,核心原因是异步操作的执行顺序问题,咱们结合你的代码一步步分析:
你的原代码
const http = require('http'); const fs = require('fs'); http.createServer(testfunc).listen(3333); function testfunc(req,res) { if (req.method === 'GET'){ fs.readFile('index.html', function(err,data){ res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.write("Hi"); }); res.end(); }; };
错误原因拆解
fs.readFile是一个异步函数,它不会阻塞后续代码的执行:
- 当代码执行到
fs.readFile时,Node.js会把文件读取任务放到后台处理,然后立刻继续执行后面的res.end()——这一步会直接结束HTTP响应,关闭整个响应流。 - 等文件读取完成后,回调函数才会被触发,但此时响应流已经被
res.end()关闭了,这时候再调用res.write()去写内容,就会触发write after end的错误。
正确的写法
你需要把res.end()移到fs.readFile的回调函数内部,确保所有响应内容都写完之后再结束响应:
const http = require('http'); const fs = require('fs'); http.createServer(testfunc).listen(3333); function testfunc(req,res) { if (req.method === 'GET'){ fs.readFile('index.html', function(err,data){ // 别忘了处理文件读取失败的情况 if (err) { res.writeHead(500, {'Content-Type': 'text/plain'}); res.write('Failed to read index.html'); res.end(); return; } res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.write("Hi"); // 所有内容写入完成后,再结束响应 res.end(); }); }; };
这样调整后,只有当文件内容和额外的"Hi"都写入响应流后,才会调用res.end()关闭流,自然就不会再出现错误了。
内容的提问来源于stack exchange,提问作者Seshu Ss
相关产品推荐
相关产品推荐

