如何修复Node.js中的‘write after end’错误并实现Gradle构建完成后展示build.html页面
修复Node.js中"write after end"错误并实现构建后跳转页面
兄弟,我一眼就看出问题所在了——你遇到的write after end错误,核心原因是HTTP响应被重复发送了。咱们一步步拆解问题,再给出修复方案:
错误根源分析
当POST请求进来时,你的代码进入了if(req.method == 'POST')分支处理,但Gradle构建是异步操作,而分支外的默认响应逻辑(发送index.html)会立刻执行,直接结束了res响应对象。等后续构建完成后,你再尝试往已经关闭的响应流里写入build.html的内容,自然就触发了write after end错误。
另外还有个小问题:你在data事件里重复解析POST数据是多余的,因为data事件会多次触发,每次只拿到部分数据,这时候解析会导致数据不完整。
修复后的完整代码
const http = require('http'); const fs = require('fs'); const { spawn } = require("child_process"); var qs = require('querystring'); const server = http.createServer((req, res)=> { if (req.method == 'POST') { var body = ''; console.log("Post received"); req.on('data', function (data) { body += data; // 限制POST数据大小,防止恶意请求 if (body.length > 1e6) req.connection.destroy(); }); req.on('end', function () { var post = qs.parse(body); // 执行Gradle构建 const ls = spawn("./gradlew", ["build"]); ls.stderr.on("data", data => { console.log(`stderr: ${data}`); }); ls.on('error', (error) => { console.log(`error: ${error.message}`); // 构建出错时返回错误页面,避免客户端一直等待 res.writeHead(500, {'Content-type': 'text/html'}); res.end('<h1>构建失败,请查看终端日志</h1>'); }); ls.on("close", code => { console.log(`构建进程退出,代码:${code}`); if (code === 0) { console.log("Build success"); const readStream = fs.createReadStream('./build.html'); res.writeHead(200, {'Content-type': 'text/html'}); readStream.pipe(res); } else { res.writeHead(500, {'Content-type': 'text/html'}); res.end('<h1>构建失败,请查看终端日志</h1>'); } }); }); // 关键:添加return阻止后续默认响应逻辑执行 return; } // 非POST请求,返回index.html const readStream = fs.createReadStream('./index.html'); res.writeHead(200, {'Content-type': 'text/html'}); readStream.pipe(res); }); server.listen('3000'); console.log('服务器运行在http://localhost:3000');
关键修复点说明
- 添加return语句:在POST分支末尾加上
return,确保处理POST请求时,不会执行后面的默认响应逻辑,避免提前关闭响应流 - 优化POST数据解析:只在
end事件中解析一次完整的POST数据,保证数据完整性 - 完善错误处理:当Gradle构建出错(进程退出码非0)时,给客户端返回明确的错误提示,避免客户端长时间等待
- 判断构建结果:根据进程退出码判断构建是否成功,成功返回
build.html,失败返回错误页面
这样修改后,用户提交表单触发POST请求时,服务器会等待Gradle构建完成,再根据结果返回对应页面,再也不会出现write after end的错误啦!
内容的提问来源于stack exchange,提问作者Sarath C
相关产品推荐
相关产品推荐

