My code is a first node process (login) calling a second node process (api)
Every thing is fine until I call the http.get request (for a POST) The error occurs when it calls the
request.write(body)
I get the following error "Error [ERR_STREAM_WRITE_AFTER_END]: write after end"
Here is the code of the caller :
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)
})
On the other side the called party :
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)
})
From the docs for http.get()
The only difference between this method and
http.request()
is that it sets the method to GET by default and callsreq.end()
automatically.
You cannot call request.write()
since the write buffer has already been closed. Why are you using http.get()
to attempt a POST
request anyway?
Node.js supports the modern Fetch API since v18.0.0. I would strongly suggest you use it instead of the http
module
app.post('/login', async (req, res, next) => {
const { password } = req.body;
try {
const response = await fetch(`http://${api.host}:${api.port}/api/login`, {
method: 'POST',
body: JSON.stringify({ appid, authtoken, password }),
headers: { 'content-type': 'application/json' },
});
if (!response.ok) {
console.error('Request failed', response.status, await response.text());
throw new Error(`Upstream request failed: ${response.status}`);
}
const data = await response.json();
console.log('data', data); // you sure that's all you want to do with data?
res.end();
} catch (e) {
next(e);
}
});