I new to nodeJS and i want to show my request result body to browser using express, but my code throw an error like this, i've try to use array.push() but not working too
ERROR
node:_http_outgoing:576
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:371:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
at ServerResponse.header (C:\xampp\htdocs\#masgalih\tt\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (C:\xampp\htdocs\#masgalih\tt\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\xampp\htdocs\#masgalih\tt\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:\xampp\htdocs\#masgalih\tt\node_modules\express\lib\response.js:158:21)
at Request._callback (C:\xampp\htdocs\#masgalih\tt\index.js:12:24)
at Request.self.callback (C:\xampp\htdocs\#masgalih\tt\node_modules\request\request.js:185:22)
at Request.emit (node:events:390:28)
at Request.<anonymous> (C:\xampp\htdocs\#masgalih\tt\node_modules\request\request.js:1154:10) {
code: 'ERR_HTTP_HEADERS_SENT'
}
CODE
const request = require('request')
const express = require('express')
const app = express()
app.get('/getdata', (req, res) => {
if (req.query.id !== undefined && req.query.id !== '') {
request('http://localhost/myApi/index.php?id=' + req.query.id, (err, response, body) => {
return res.send({
status: 200,
data: body
})
})
}
return res.send({
status: 400,
msg: 'Parameter invalid'
})
})
app.listen(2000)
The app.get('/getdata'); has two different res.send();'s in it. This by itself is alright, but what is happening is that when the function in app.get('/getdata'); runs, it checks that if statement first. If the if is false, it skips right past and everything runs fine.
But what if the if statement is true? Well, the code inside the the statement runs and sends a request to the specified URL and waits for a response. While it's waiting though, JavaScript continues running your code because JavaScript is asynchronous.
So the second res.send() runs, but then the response to the request is received, and therefore sends a second (the first in chronological order) res.send(), which is why the error is saying you are trying to set headers (the main information in a nodejs request) after you just sent it to the client.
What the code should do is instead only run on or the other, not both. We can achieve this by putting the second res.send() in an else, which means it only runs if the if statement is false. So something like this:
const request = require('request')
const express = require('express')
const app = express()
app.get('/getdata', (req, res) => {
if (req.query.id !== undefined && req.query.id !== '') {
request('http://localhost/myApi/index.php?id=' + req.query.id, (err, response, body) => {
return res.send({
status: 200,
data: body
})
})
} else {
return res.send({
status: 400,
msg: 'Parameter invalid'
})
}
})
app.listen(2000)
Related
Am trying to send a request to the server to save a post. Am using Nextjs and everytime i try to send it gives me this Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.
Here is my code
Post.js
async function uploadPost(post) {
const response = await fetch('/api/savePost', {
method: 'POST',
body: post,
});
if(!response.ok) {
throw new Error('Failed to post')
}
return await response.json();
}
savePost.js
export const config = {
api: {
bodyParser: false,
},
}
export default const post = async (req, res) => {
if (req.method !== 'POST') {
return res.status(405).json({
message: 'Method not allowed'
})
}
// const postData = JSON.parse(req.body);
const savedPost = await prisma.post.create({
data: req.body
});
res.status(200).json({message: 'Post saved successfully'})
res.json(savedPost)
};
Am using Prisma for the db
I get this error
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:371:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
at NodeNextResponse.setHeader (C:\Users\user\Documents\My Received Files\js\twitter-clone\node_modules\next\dist\server\base-http\node.js:56:19)
at DevServer.renderError (C:\Users\user\Documents\My Received Files\js\twitter-clone\node_modules\next\dist\server\base-server.js:1134:17)
at DevServer.renderError (C:\Users\user\Documents\My Received Files\js\twitter-clone\node_modules\next\dist\server\next-server.js:493:22)
at DevServer.run (C:\Users\user\Documents\My Received Files\js\twitter-clone\node_modules\next\dist\server\dev\next-dev-server.js:452:35)
at async DevServer.handleRequest (C:\Users\user\Documents\My Received Files\js\twitter-clone\node_modules\next\dist\server\base-server.js:307:20) {
code: 'ERR_HTTP_HEADERS_SENT'
}
error - uncaughtException: Error [ERR_STREAM_WRITE_AFTER_END]: write after end
res.status(200).json({message: 'Post saved successfully'})
res.json(savedPost)
Here you send 2 messages back. Both with 200 code. This is what "write after send" means.
The first message set's the header and goes back.
Then after that you try to do it again, but the header is already sent.
// res.json() equals to res.status(200).json()
// You can merge res.status(200).json({message: 'Post saved successfully', savedPost: savedPost})
I'm trying to send some data in NodeJS from one localhost server to another, but I'm getting a nasty error. On the server that receives the request it appears the request goes through because I'm getting an object logged to the terminal there, except its properties are null (they're supposed to be set to the properties in the req body, or null).
I get the error even if I try with Axios, which tells me that it’s not an issue with http.request or Axios. If anyone could help me understand what's going on I'd appreciate it.
Error:
events.js:377
throw er; // Unhandled 'error' event
^
Error: write EPROTO 8669511168:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:94:16)
Emitted 'error' event on ClientRequest instance
{
errno: -100,
code: 'EPROTO',
syscall: 'write'
}
The project sending the request looks like this:
Resources file
const http = require('http');
const options = {
host: 'localhost',
port: 3000,
path: '/create',
method: 'POST',
header: {
'Content-Type':'application/json'
}
}
const body = {
inquiryTotal: ‘20.00’
}
const stringifiedBody = JSON.stringify(body)
module.exports.Inquiries = {
create: () => {
req = http.request(options, (res) => {
console.log(res);
});
req.write(stringifiedBody); // this is an object that's already stringified to JSON
req.end();
/*axios.post('localhost:3000/v1/orders/create', {
orderTotal: '21.00'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})*/
}
}
Server sending request:
const resource = require('./lib/resource');
// create server code
resource.Inquiries.create;
Assuming you are correctly setup your API endpoint, you can try this (added some comments inside the code):
const axios = require("axios").default;
const body = {
inquiryTotal: "20.00" // Use single-qupte ('') or double-quote ("") here and don't use back-quote (``)
};
module.exports.Inquiries = {
create: () => {
axios
.post("http://localhost:3000/v1/orders/create", body) // Add http:// in the beginning of your url
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}
};
I've got the following block of code:
router.put("/:_id", async (req: Request, res: Response) => {
try {
// Create the updated artist variable
const artist: IArtist = req.body;
const updatedArtist = await Artist.findOneAndUpdate({_id: req.params._id}, artist);
return res.sendStatus(200).json(updatedArtist);
} catch (err) {
// console.log(err);
return res.sendStatus(400).send("Couldn't update artist");
}
});
This throws the following error:
(node:32408) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:561:11)
at ServerResponse.header (C:\Users\thimo\Documents\GitHub\FlexTix\server\node_modules\express\lib\response.js:771:10)
at ServerResponse.contentType (C:\Users\thimo\Documents\GitHub\FlexTix\server\node_modules\express\lib\response.js:599:15)
at ServerResponse.sendStatus (C:\Users\thimo\Documents\GitHub\FlexTix\server\node_modules\express\lib\response.js:357:8)
at C:\Users\thimo\Documents\GitHub\FlexTix\server\src\routes\artists.ts:44:20
at step (C:\Users\thimo\Documents\GitHub\FlexTix\server\src\routes\artists.ts:33:23)
at Object.next (C:\Users\thimo\Documents\GitHub\FlexTix\server\src\routes\artists.ts:14:53)
at fulfilled (C:\Users\thimo\Documents\GitHub\FlexTix\server\src\routes\artists.ts:5:58)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
As far as I know, I'm only sending one header. How could I fix this problem?
You need to use .status() instead of .sendStatus(). When you use .json() or .send() on top of .sendStatus() - express tries to set additional headers on top of response that is already sent due to .sendStatus()
I have been struggling with the problem presented in the topic for some time. Can anyone help me with that? If I have to clarify something, please ask questions. I've read some potential solutions to this problem, but it didn't work for me. Every clue will be appreciated.
Code:
const post = (url) => new Promise((resolve, reject) => {
var options = {
url,
headers: {
"Api-Key": apiKey,
"Authorization": basicToken
},
agentOptions: {
pfx,
passphrase: ""
}
};
request.get(options, (error, response, body) => {
if (error) {
reject("error");
} else if (response.status === "403") {
reject("error");
} else {
console.log(`response: ${JSON.stringify(response)} ${response.status}.`);
console.log("body: " + body);
if (body == "")
body = "{}";
let output = JSON.parse(body);
if (output.length == 0)
reject("no data");
resolve(output);
}
});
});
Error logs:
(node:10) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
2021-06-14 20:31:18.938 CEST
at ServerResponse.setHeader (_http_outgoing.js:470:11)
2021-06-14 20:31:18.938 CEST
at ServerResponse.header (/workspace/node_modules/express/lib/response.js:771:10)
2021-06-14 20:31:18.938 CEST
at ServerResponse.send (/workspace/node_modules/express/lib/response.js:170:12)
2021-06-14 20:31:18.938 CEST
at Object.exports.fulfillments (/workspace/index.js:16:25)
2021-06-14 20:31:18.938 CEST
at process._tickCallback (internal/process/next_tick.js:68:7)
Code where I am using express:
const index = require("./index.js");
const express = require("express");
const app = express();
const port = process.env.PORT || 8080
app.use(express.json());
app.post("/", async(req, res) => {
await index.fulfillments(req, res);
});
app.listen(port, () => console.log(`App listening on port ${port}!`));
We've all had that issue once before xD. Basically, somewhere in your code, you are attempting to set a response header after the response has already been returned.
I suggest taking a look through your reponse (fulfillments) function as it could be as simple as missing a return statement after responding to a request.
So given that I can't run these two post requests at the same time in my client, I'm trying to run the second post in the .then section of the first post. Which has always worked fine on my other projects. But for some reason when the second post request fires my server doesn't reply. When I check the console of the server, I notice it crashed and there's an error message (at the bottom of this post).
What could be causing this???
I have put breakpoints on the second post request in my server's code, and noticed the breakpoints don't even get hit. The server crashes before hitting and giving me the option to continue.
Client Code (gets fired when user presses a button):
$scope.searchCharacter = function(){
var request = {name: $scope.charName, realm: $scope.selectedRealm};
//First post request
$http.post('/searchCharacter', request)
.then(function(response) {
//sets some variables
var id = 0;
//Second post request
$http.post('/helloworld', id)
.then(function(response) {
//sets some more variables
debugger;
});
});
}
Server Code:
//First post request
app.post('/searchCharacter', jsonParser, function (req, res) {
blizzard.wow.character(['profile', 'stats', 'items', 'statistics'], { origin: 'us', realm: req.body.realm.name, name: req.body.name })
.then(response => {
if(response.status != 200){
res.send("That character doesn't exist! Please enter a valid character name.");
} else {
console.log(response.data);
res.send(response.data);
}
});
});
//Second Post Request
app.post('/helloworld', jsonParser, function (req, res) {
console.log(req.body);
res.send("hello");
});
Error message:
SyntaxError: Unexpected token #
at Object.parse (native)
at createStrictSyntaxError
(c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\types\json.js:157:10)
at parse (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\types\json.js:83:15)
at c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:224:16)
at done (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd
(c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:273:7)
at emitNone (events.js:67:13)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:921:12)
Try this:
$scope.searchCharacter = function(){
var request = {name: $scope.charName, realm: $scope.selectedRealm};
//First post request
$http.post('/searchCharacter', request)
.then(function(response) {
//sets some variables
var id = 0;
//Second post request (append id to route).
$http.post('/helloworld/' + id)
.then(function(response) {
//sets some more variables
debugger;
});
});
}
//First post request
app.post('/searchCharacter', jsonParser, function (req, res) {
blizzard.wow.character(['profile', 'stats', 'items', 'statistics'], { origin: 'us', realm: req.body.realm.name, name: req.body.name })
.then(response => {
if(response.status != 200){
res.send("That character doesn't exist! Please enter a valid character name.");
} else {
console.log(response.data);
res.send(response.data);
}
});
});
//Second Post Request (get id from req.params.id)
app.post('/helloworld/:id', function (req, res) {
console.log(req.params.id);
res.send("hello");
});
It appends id to the helloworld request, and defines a route helloworld/:id using req.params.id to pull the id out of the request.
Facepalm I was using var id = 0 and passing it to my function without realizing it needed to be passed as either an object or a param. Thanks to those who commented!