You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js跨进程用Express发起POST请求时触发write after end错误

解决Node.js http.get发起POST请求时的Error [ERR_STREAM_WRITE_AFTER_END]错误

问题描述

Node.js登录进程调用另一个Node.js API进程时,其余流程正常,但使用http.get发起POST请求,执行request.write(body)语句时出现错误:Error [ERR_STREAM_WRITE_AFTER_END]: write after end。

相关代码

调用方代码

app.enable('strict routing');
app.disable('x-powered-by');

app.use(express.json());
app.use(express.urlencoded({
    extended:true
}));
 
assert(hbs);
app.set('view engine','hbs');
app.engine('hbs',hbs.create().__express)

svr.server = http.createServer(app)

app.get('/',function(req,res,next) {
    res.render("login.hbs")
})
app.post('/login', async function(req,res) {
    console.log("post login",req.body)

    const password = req.body.password
    console.log('password',password)

    const body = JSON.stringify({
        appid:appid,
        authtoken:authtoken,
        password:password        
    })

    const options = {
        host: api.host,
        port: api.port,
        path: '/api/login',
        method: "POST",
        headers: {
            'Content-Type':'application/json',
            'Content-Length':Buffer.byteLength(body)
        },
    }

    console.log('options',options)

//    var data = ''
    var request = http.get(options, function(res) {
        let data = ''
        res.setEncoding('utf8')
        res.on('data',function(chunk) {
            data += chunk
        })
        res.on('end',function() {
            console.log('data',JSON.parse(data))
        })
        res.on('error',function(e) {
            console.log('err',e.toString())
        })
    })
    request.write(body)
    request.end()

    res.end()
})

app.listen(svr.port,svr.host,function() {
    console.log('http listen',svr.port,svr.host)
})

被调用方代码

app.enable('strict routing');
app.disable('x-powered-by');

app.use(express.json())
app.use(express.urlencoded({
    extended:true
}))

svr.server = http.createServer(app)

app.get('*', async function(req,res,next) {
    console.log('all')
    next()
}) 
app.post('/api/login', async function(req,res) {
    console.log("post api login",req.body)

    const account = ''
    res.status(200).json({ account:account, session:uuid.v4() })
    // res.status(400).json({ error:'server error message' })
})

app.listen(svr.port,svr.host,function() {
    console.log('http listen',svr.port,svr.host)
})

解决方案

核心问题

http.get是http.request的封装方法,它会自动调用request.end()来结束请求流,因此当你手动调用request.write(body)和request.end()时,请求流已经被关闭,从而触发write after end错误。

修改后的调用方代码

将http.get替换为http.request,并完善响应和错误处理逻辑:

app.post('/login', async function(req,res) {
    console.log("post login",req.body)

    const password = req.body.password
    console.log('password',password)

    const body = JSON.stringify({
        appid:appid,
        authtoken:authtoken,
        password:password        
    })

    const options = {
        host: api.host,
        port: api.port,
        path: '/api/login',
        method: "POST",
        headers: {
            'Content-Type':'application/json',
            'Content-Length':Buffer.byteLength(body)
        },
    }

    console.log('options',options)

    var request = http.request(options, function(response) {
        let data = ''
        response.setEncoding('utf8')
        response.on('data',function(chunk) {
            data += chunk
        })
        response.on('end',function() {
            console.log('data',JSON.parse(data))
            // 等待API返回结果后,再给前端响应
            res.end(JSON.stringify(JSON.parse(data)))
        })
        response.on('error',function(e) {
            console.log('err',e.toString())
            res.status(500).end(e.toString())
        })
    })
    
    // 捕获请求自身的异常
    request.on('error', function(e) {
        console.log('request error', e.toString())
        res.status(500).end(e.toString())
    })

    request.write(body)
    request.end()
})

额外优化说明

  1. 原代码中res.end()直接返回空响应,修改后等待API调用完成再返回结果,避免前端提前收到无效响应。
  2. 添加request对象的错误监听,覆盖请求发起阶段的异常场景。

内容的提问来源于stack exchange,提问作者Gilles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:52:35