Express won't send headers - node.js

I've done this from scratch and it still gives me an error...
I've run
express test
then
cd test && npm install
I've edited the app.js adding a route such this:
app.get('/test',function(req,res) {
res.writeHead(200, {"Content-Type": "application/json"});
return res.send('{"a":3}');
});
Then I've run node
node app.js
And when I try to access http://server/test I get
Error: Can't set headers after they are sent.
I'm using
Node v4.2.1, Express 2.5.8, npm 3.4.0.
This just happens with Express, if I create a simple server on Node I can use writeHead.

When res.writeHead(200, {"Content-Type": "application/json"});,you send all the response headers to the client,so you can not send header again.
Because res.send is the function of express's response object,I look the source code of this send function:
chunk is what you send here : String('{"a":3}')
this.set('Content-Type', setCharset(type, 'utf-8')) here express helps us concat our content-type with utf-8 so server needs to send header again
That is why you get the error.
Ps.
Sorry for my bad english and I hope you understand what I try to explain.

What about using res.setHeader
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.setHeader("Content-Type","application/json");
res.send('{}');
});
var server = app.listen(3000, function () {
var host = "localhost";
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});

Related

How to recieve a file using request.get()?

I am writing a server that is meant to serve and receive files. It is written in node.js, using express.js. I also have a client, also written in node, which is meant to send a request to the server and receive the files on the server.
Server-side
const express = require("express");
const app = express();
const file = "./samplefiles/Helloworld.txt";
app.get("/", (res)=>{
res.download(file);
});
module.exports = app; //this exports to server.js
const http = require("http");
const app = require("./app.js);
const port = 8080;
const server = http.createServer(app);
server.listen(port, () => {
console.clear();
console.log("server running");
})
Client-side
const request = require("request");
request.get("http://localhost:8080/", (req, body) => {
console.log(body);
console.log(res);
});
If I try to access it by my browser I am asked what I want to do with the file, it works. However, Is I run my client-side code it prints the body and the res(being null). I expected the file name and it's content to be in the body but only the content of the file was in the body.
I want to receive the whole file, is possible, or at least get the name of it so that I can "make" a copy of it on the client-side.
Change code your server side to:
const port = 8080;
const express = require("express");
const app = express();
const path = require('path');
app.get("/", function(req, res){
res.sendFile(path.join(__dirname, 'app.js'));
});
app.listen(port, () => {
console.clear();
console.log("server running");
});
Change code your client-side to:
var request = require('request');
request('http://localhost:8080/', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print data of your file
});
You need to install request npm i request for client side
You can serve up any files you want with express static method:
app.use(express.static('public'))
in this case just put all the files you want to serve in folder called public and then you can access it by localhost:8080/Helloworld.txt.
I ended up working around it.
I sent the file name as a header and was thus able to create a replica of the file I wanted to download using the body info and the filenameheader.

Node.js + React: How to POST

Follow on from this question: Axios can GET but not POST to the same URL
I've been trying to figure this out for too long now.
I want to POST from my React app to a .JSON file. Can anyone tell me what I'm doing wrong?
My AJAX POST function using axios always returns a 404. I'm listening for it on the node server but app.post never fires.
Thanks.
POST request from my React app:
postJson = (postJsonData) => {
axios.post('./postJson/', {
postJsonData
})
.then(function (response) {
console.log("success!");
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
app.js (node server):
/*========== Default Setup for node server copied from node website ==========*/
const http = require('http');
const hostname = '127.0.0.1';
const port = 3001;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
/*========== Listen for POST (Trying to get the data from my REACT app
- will then assign it to "obj" below) ==========*/
var express = require("express");
var myParser = require("body-parser");
var app = express();
app.post("./postJson/", function(request, response) {
console.log("MURRRR");
console.log(request.body); //This prints the JSON document received (if it is a JSON document)
/*=== JSON Stuff ===*/
var jsonfile = require('jsonfile')
var file = './scene-setup.json'
var obj = {name: 'JP'}
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
});
//Start the server and make it listen for connections on port 3000
app.listen(3000, function(){
console.log("server is listening to 3000");
});
Two things I noticed:
Your post endpoint doesn't need a leading "." I would make it just "/postJson"
Make sure you are posting to "http://localhost:3000/postJson"
Make sure you have the network tab open to see the actual URL you are requesting to.
Cheers
Turns out both react and my node server were running on localhost:3000 simultaneously which is apparently not okay.
Running my node server on localhost:3001 from a new command line window allowed me to do both at the same time.
Not sure how this would work when making a production build though.

Axios can GET but not POST to the same URL

I'm building a react app
In one component I'm writing this GET request which works:
In another component I'm writing this POST request:
Which then returns this 404 error:
And I have no idea how my GET works but my POST returns 404:not found when I'm requesting the same file both times?
UPDATE:
I'm running a node.js server now but it's a bit of a frankenstein's monster as this really isn't an area I have an understanding of. Does anyone know what I'm doing wrong?
// Server setup from node.js website
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
// Trying to listen for data from React app to feed into JSON (broken)
var express = require("express");
var myParser = require("body-parser");
var app = express();
app.use(myParser.urlencoded({extended : true}));
app.post("/scene-setup.json", function(request, response) {
console.log(request.body); //This prints the JSON document received (if it is a JSON document)
});
app.listen(3001);
// Updating JSON file with "obj" (working)
var jsonfile = require('jsonfile')
var file = './scene-setup.json'
var obj = {name: 'JP'}
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
Axios is used for making HTTP requests. So, you should have a backend server running that can handle these requests. I am not sure what exactly is the data that you want to save. If you need access to that data, should be saving it on the backend.
If you want to save some data just on the client side, HTML5 filesystem API might be something you want to look at. It can manage some data in the limited sandboxed part of user's filesystem.

Node.js server with http get json

I want to create a simple Node.js server to do the following :
With my application I just do the command http.get(Node.Js_Server_address/json) to get the json file data stored on my server.
Could please help me with a tutorial? Any help would be appreciated!
This is very simple example of node.js server:
var app = require('./app');
var http = require('http');
var server = http.createServer(app);
server.listen(8080, function() {
console.log("listening to: http://127.0.0.1:8080");
});
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
there is a nice tutorial here and here ...
you can use npm to install node.js and all the packages that you need for it.
hope it helps.
There are lots of examples on this topic, i think you should make some googling before next time.
You can create a REST server via express module of nodeJs. In your server folder use npm install express to download express module. You can get more information about express from here. After that create a server.js file in your server folder.In server.js
var express = require('express');
var app = express();
var PORT = 8080;
/* req stands for request, res stands for response */
app.get('/json',function(req,res){
res.json(yourData);
})
app.listen(PORT,function(){
console.log('Express is listening port:' + PORT + '!');
})
So this should do the work. Let me know if this helps you.

Creating web server with express (node.js)

js and am trying to create a web server and server side code for my web application.
I understand express is used to get access to all static files.
I am trying to start a simple server using express as follows:
var express = require("express");
var url = require("url");
var http = require("http");
var port = 3000;
var app = express();
app.use(express.static(__dirname + "/Client"));
http.createServer(app).listen(port, function(req,res){
console.log("Server running at: " + "http://" + port);
res.writeHead(200,{
"Content-Type":"text/plain"
});
});
I cant seem to do anything with my res variable in my callback, which I am trying to use as a response object. Allowing me to do things like:
res.end(¨hello world¨);
Is this callback even allowed, or how can I start sending responses etc. I am on virtual box (linux) machine, and using res always gives error (undefined methods etc.). Thanks in advance,
http.createServer(app).listen(port, [hostname], [backlog], [callback])
There are no parameters given to the callback function. This is why req and res are undefined.
So you may change your code to:
app.listen(port, function(){
console.log("Server running at: " + "http://localhost:" + port);
});
app.get('/', function(req,res) {
res.status(200).send('Hello World!')
})
So take a look at the documentation of app.listen() and app.get()

Resources