Http request with node? - javascript

How do I make a Http request with node.js that is equivalent to this code:
curl -X PUT http://localhost:3000/users/1

For others googling this question, the accepted answer is no longer correct and has been deprecated.
The correct method (as of this writing) is to use the http.request method as described here: nodejitsu example
Code example (from the above article, modified to answer the question):
var http = require('http');
var options = {
host: 'localhost',
path: '/users/1',
port: 3000,
method: 'PUT'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
console.log(str);
});
}
http.request(options, callback).end();

Use the http client.
Something along these lines:
var http = require('http');
var client = http.createClient(3000, 'localhost');
var request = client.request('PUT', '/users/1');
request.write("stuff");
request.end();
request.on("response", function (response) {
// handle the response
});

var http = require('http');
var client = http.createClient(1337, 'localhost');
var request = client.request('PUT', '/users/1');
request.write("stuff");
request.end();
request.on("response", function (response) {
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});

Related

Node Beginner: User input on a webpage to alter JSON request?

I have a text input field on my webpage, userID in which the user specifies a bit of information that will be appended to a JSON request. The function fetchJSON is called when the user submits their info.
The code is as follows:
function fetchJSON(){
//get user input
var userID = document.getElementById("userID").value;
//create request and options
var https= require("https");
var options = {
host: "api.example.com",
path: "/GetHistory/V001/account_id=" + userID,
method: "GET"
};
//handle request
var request = https.request(options, function(response){
var body = "";
response.on("data", function(chunk){
body += chunk.toString("utf8");
});
response.on("end", function(){
var json = JSON.parse(body);
console.log(json);
});
});
request.end();
}
The code works when I run it from terminal with the userID hardcoded (node main.js) but I am in the dark as to how I can run it from a webpage with user defined input.
Thanks for any help!
First of all, node.js can't manipulate the client-side DOM.
So you need to pass the variable to server, so using express as mentioned in the comments after you have generated a basic website
setup a basic get route
app.get('/api/getprofilebyid/:id',function(req,res){
//get user input
var userID = req.params.id; //document.getElementById("userID").value;
//create request and options
var https= require("https");
var options = {
host: "api.example.com",
path: "/GetHistory/V001/account_id=" + userID,
method: "GET"
};
//handle request
var request = https.request(options, function(response){
var body = "";
response.on("data", function(chunk){
body += chunk.toString("utf8");
});
response.on('error',function(err){
res.json(500,{'error':err}); // an error occured.
});
response.on("end", function(){
request.end(); // and the request.
res.json(200,body); // output json
});
});
});
and request using ajax or simply browse to url..
using jQuery ajax $.get on client-side
var userID = document.getElementById("userID").value;
$.get('/api/getprofilebyid/'+userID,function(response){
// handle response
});

How to get data from response to get request in node.js?

Trying to make get request from node.js with express module. Here is code of this piece:
var req = http.request(options, function(res) {
res.on('data', function (chunk){
});
});
req.end();
But can't understand how to receive data from responses body, i tried res.body. or res.data. Didn't work.
The data arrives in the chunk parameter. Parts of it anyway. You need to pick up and join all the chunks into a complete response. Copy-paste example from http://docs.nodejitsu.com/articles/HTTP/clients/how-to-create-a-HTTP-request:
var http = require('http');
//The url we want is: 'www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
console.log(str);
});
}
http.request(options, callback).end();

nodejs multiple http requests in loop

I'm trying to make simple feed reader in node and I'm facing a problem with multiple requests in node.js.
For example, I got table with urls something like:
urls = [
"http://url1.com/rss.xml",
"http://url2.com",
"http://url3.com"];
Now I want to get contents of each url. First idea was to use for(var i in urls) but it's not good idea. the best option would be to do it asynchronously but I don't know how to make it.
Any ideas?
EDIT:
I got this code:
var data = [];
for(var i = 0; i<urls.length; i++){
http.get(urls[i], function(response){
console.log('Reponse: ', response.statusCode, ' from url: ', urls[i]);
var body = '';
response.on('data', function(chunk){
body += chunk;
});
response.on('end', function() {
data.push(body);
});
}).on('error', function(e){
console.log('Error: ', e.message);
});
}
Problem is that first is call line "http.get..." for each element in loop and after that event response.on('data') is called and after that response.on('end'). It makes mess and I don't know how to handle this.
I know this is an old question, but I think a better solution would be to use JavaScripts Promise.all():
const request = require('request-promise');
const urls = ["http://www.google.com", "http://www.example.com"];
const promises = urls.map(url => request(url));
Promise.all(promises).then((data) => {
// data = [promise1,promise2]
});
By default node http requests are asynchronous. You can start them sequentially in your code and call a function that'll start when all requests are done. You can either do it by hand (count the finished vs started request) or use async.js
This is the no-dependency way (error checking omitted):
var http = require('http');
var urls = ["http://www.google.com", "http://www.example.com"];
var responses = [];
var completed_requests = 0;
for (i in urls) {
http.get(urls[i], function(res) {
responses.push(res);
completed_requests++;
if (completed_requests == urls.length) {
// All download done, process responses array
console.log(responses);
}
});
}
You need to check that on end (data complete event) has been called the exact number of requests... Here's a working example:
var http = require('http');
var urls = ['http://adrianmejia.com/atom.xml', 'http://twitrss.me/twitter_user_to_rss/?user=amejiarosario'];
var completed_requests = 0;
urls.forEach(function(url) {
var responses = [];
http.get(url, function(res) {
res.on('data', function(chunk){
responses.push(chunk);
});
res.on('end', function(){
if (completed_requests++ == urls.length - 1) {
// All downloads are completed
console.log('body:', responses.join());
}
});
});
})
You can use any promise library with ".all" implementation. I use RSVP library, Its simple enough.
var downloadFileList = [url:'http://stuff',dataname:'filename to download']
var ddownload = downloadFileList.map(function(id){
var dataname = id.dataname;
var url = id.url;
return new RSVP.Promise(function(fulfill, reject) {
var stream = fs.createWriteStream(dataname);
stream.on('close', function() {
console.log(dataname+' downloaded');
fulfill();
});
request(url).on('error', function(err) {
console.log(err);
reject();
}).pipe(stream);
});
});
return new RSVP.hashSettled(ddownload);
Promise.allSettled will not stop at error. It make sure you process all responses, even if some have an error.
Promise.allSettled(promises)
.then((data) => {
// do your stuff here
})
.catch((err) => {
console.log(JSON.stringify(err, null, 4));
});
The problem can be easily solved using closure. Make a function to handle the request and call that function in the loop. Every time the function would be called, it would have it's own lexical scope and using closure, it would be able to retain the address of the URL even if the loop ends. And even is the response is in streams, closure would handle that stuff too.
const request = require("request");
function getTheUrl(data) {
var options = {
url: "https://jsonplaceholder.typicode.com/posts/" + data
}
return options
}
function consoleTheResult(url) {
request(url, function (err, res, body) {
console.log(url);
});
}
for (var i = 0; i < 10; i++) {
consoleTheResult(getTheUrl(i))
}

retrieve page source using node js

I have to do retrieve the page source of a page with nodejs, but the page that I want to retrieve isn't always the same.
I have 2 files server.js that is listening and when he receive A connections he call load.js that retrive the sourse of a non defined page, my code is this:
server.js
var net = require('net');
var loadFb = require('./load.js');
var HOST = 'localhost';
var PORT = 9051;
// Create a server instance, and chain the listen function to it
// The function passed to net.createServer() becomes the event handler for the 'connection' event
// The sock object the callback function receives UNIQUE for each connection
net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('User request profile of: ' + data);
// Write the data back to the socket, the client will receive it as data from the server
//here I have to call test.js
//how
sock.write(data);
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
the other file is this:
var https = require('https');
var options = {
host: 'graph.facebook.com',
port: 443,
path: '/dario.vettore',
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
//console.log(pageData);
return pageData;
});
res.on('end', function(){
//response.send(pageData)
});
});
How can I ask from the first file (server.js) to the second file to retrive for it the page source from the second file, But the page that I want to get the source can change isn't always the same..
In your second file (I'm assuming that's the one named loadFb.js), you want to export a function, instead of calling the code right away.
Node caches its modules so when you require() them, the code only gets run once.
The second file should look something like this:
var https = require('https');
module.exports = function(path, callback) {
var options = {
host: 'graph.facebook.com',
port: 443,
path: path,
method: 'GET'
};
var req = https.get(options, function(res) {
var pageData = "";
res.setEncoding('utf8');
res.on('data', function (chunk) {
pageData += chunk;
});
res.on('end', function(){
callback(pageData);
});
});
};
Then in your first file, you would access it like this:
loadJs('/dario.vettore', function(pageData) {
console.log(pageData);
});
This way you can execute the module code many times, with different paths.

Why is my node.js get response being truncated

I am making a request to the facebook api to get a list of friends. When I make the request through node.js, my request is always truncated. Does anyone understand why the response is being truncated?
Here is the code of my function:
var loadFriends;
loadFriends = function(access_token, callback) {
var https, options, start;
https = require('https');
start = new Date();
options = {
host: 'graph.facebook.com',
port: 443,
path: '/me/friends?access_token=' + access_token
};
return https.get(options, function(res) {
console.log("Request took:", new Date() - start, "ms");
res.setEncoding("utf8");
return res.on("data", function(responseData) {
var data;
console.log(responseData);
data = JSON.parse(responseData);
return callback(data);
});
});
};
The res.on('data') event will happen multiple times as chunks of data arrives; you need to concatenate this together to get the whole response.
http://nodejs.org/docs/v0.4.0/api/http.html#event_data_

Categories