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

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.

Related

Node js(Express framework): not able to print number API from external server to client browser

I am trying to retrieve weather API from external server and when I am console logging particular data of weather API, it's also showing on my command prompt.
But when I am using get method to show that data on browser I am only able send string data like "description": moderate rain and not number data like "temp": 27
it the crash the app.
Node js code:
//jshint esversion:6
const express = require("express");
const app = express();
const https = require("https");
app.get("/", function(req, res) {
const url = "https://api.openweathermap.org/data/2.5/weather?q=mumbai&appid=d88391210768983e6be06cdd76bdcde3&units=metric";
https.get(url, function(response) {
console.log(response.statusCode);
response.on("data", function(data) {
const weatherData = JSON.parse(data);
const temp= weatherData.main.temp;
const description= weatherData.weather[0].description;
console.log(temp);
console.log(description);
res.send(temp);
});
});
});
app.listen(3000, function() {
console.log("Server is running on port: 3000");
});
You should ideally return a json.
It can be:
res.send({temp: temp, description: description});
The res.send has to return a string/object/array/buffer.
You could do something like:
res.status(200).send(temp)
But sending json response is preferable, and you can scale it as well.
Another hack kind of solution is:
res.send("" + temp)

How do I get the recording ID from a Twilio recorded call?

My twilio code is:
const express = require('express');
const VoiceResponse = require('twilio').twiml.VoiceResponse;
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/health', (req, res) => {
res.send('ok')
})
// Returns TwiML which prompts the caller to record a message
app.post('/record', (request, response) => {
// Use the Twilio Node.js SDK to build an XML response
const twiml = new VoiceResponse();
twiml.say("Hi!");
// Use <Record> to record the caller's message
twiml.record();
console.log(twiml.toString())
response.send(twiml.toString());
});
// Create an HTTP server and listen for requests on port 3000
app.listen(PORT);
But I want to know the recording ID so I can access the raw file programatically. How would I do that?
To get the recording ID, (RecordingSid), you need to tell Twilio an action URL, with something like this:
twiml.record({
action: '/finished'
});
You can read more here: (https://www.twilio.com/docs/voice/twiml/record#attributes). Also, read about the recordingStatusCallback URL attribute, maybe that's something you need too.
Then, you need to parse the body of this second request Twilio will make to your app.
You can read more about this here: (https://www.twilio.com/blog/2016/07/how-to-receive-a-post-request-in-node-js.html).
For this you can use body-parser, which you can get with npm install body-parser.
The recording ID will be part of the parameters under body.RecordingSid.
Anyway, here is a rough modification of your code, to get started:
// npm install express body-parser
const express = require('express');
const bodyParser = require('body-parser');
const VoiceResponse = require('twilio').twiml.VoiceResponse;
const app = express();
// Tell express to use the body-parser middleware and to not parse extended bodies
app.use(bodyParser.urlencoded({
extended: false
}))
const PORT = process.env.PORT || 3000;
app.get('/health', (req, res) => {
res.send('ok')
})
// Returns TwiML which prompts the caller to record a message
app.post('/record', (request, response) => {
// Use the Twilio Node.js SDK to build an XML response
const twiml = new VoiceResponse();
twiml.say("Hi!");
// Use <Record> to record the caller's message
twiml.record({
action: '/finished'
});
console.log(twiml.toString())
response.send(twiml.toString());
});
app.post('/finished', function (req, res) {
const body = req.body;
res.set('Content-Type', 'text/plain');
res.send(``);
console.log(body);
console.log(body.RecordingSid);
});
// Create an HTTP server and listen for requests on port 3000
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
I hope this helps.

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.

Html content is not showed in NodeJS

I'm trying to create an http server. The server is created correctly but does NOT show the html content. It works when I do it without listeners. What am I failing then?
app.js
var server = require("./server.js");
server.server3((req, res, html) => {
res.writeHead(200, {"Content-Type": "text/html"});
html.pipe(res);
res.end();
}, 3000, "./index.html");
server.js
function Server3(applyFunction, port, path) {
var fs = require("fs"),
html = fs.createReadStream(path.toString().trim()), // Create stream from path
http = require("http");
html.on("data", _ => {})
.on("end", () => { // create server when all data is ready
http.createServer(function(req, res){ // createServer method
applyFunction(req, res, html); // execute the function
}).listen(+port); // add the port
});
}
module.exports.server3 = Server3;
If you're just trying to create an HTTP server on node.js, using the express framework (npm install express --save) would simplify your life a great deal. If you place the index.html file in the same directory as app.js, you can create the server with the following 5 lines of code:
// Setup Express
const express = require("express");
const app = express();
// Use main directory to find HTML file
app.use(express.static(__dirname));
// Render index.html
app.get("/", (req, res) => res.render("index"));
// Start Server on port 3000
app.listen(3000, () => console.log('Server started on port 3000'));

Resources