retrieve page source using node js - javascript

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.

Related

Log images after successful http request using Node.js

I'm creating a script that will make a request 2 times per second to a localserver of cameras network and after it gets a positive response that camera detected someone I want to log three images.
In the json config file I have the triggerURL of the server, the interval port, the dataDir where logged images should be saved and a track array which contains the url of those images and the fileName they should receive.
This is the code of the script I use after reading the JSON file:
var configGet = {
host: config.triggerURL
, port: config.interval
, method: 'GET'
};
setInterval(function () {
var request = http.request(configGet, function (response) {
var content = "";
// Handle data chunks
response.on('data', function (chunk) {
content += chunk;
});
// Once we're done streaming the response, parse it as json.
response.on('end', function () {
var data = JSON.parse(response);
if (data.track.length > 0) {
//log images
var download = function (uri, filename, callback) {
request.head(uri, function (err, res, body) {
request(uri)
.pipe(fs.createWriteStream(filename))
.on('close', callback);
});
};
for (var image in data.track) {
var path = config.dataDir + '/' + image.fileName
download(image.url, path.format(config.timestamp), function () {
console.log('done');
});
}
}
});
// Report errors
request.on('error', function (error) {
console.log("Error while calling endpoint.", error);
});
request.end();
}, 500);
});
I have the following questions:
This method produces some kind of error with the download process of the images.Can you identify it?
Is there a better way of doing this process?
Without running the code or deeper inspection; should not "data = JSON.parse(response)" rather be "data = JSON.parse(content)"? Also, if data is undefined or does not contain "track" the "if (data.track.length > 0)" will throw an error. This can be fixed with "if (data && data.track && data.track.length > 0)".
I can not think of a very much better way. I would break it up more in functions to make the code more clear though.

Socket.IO always emits to last connected client

I have a problem with Socket.IO (Node.JS).
I try to emit something to a client that makes a request, but Socket.IO answers to the latest connected client.
For example: I connect with my computer to the site, and connect with my laptop after that. Now I make a request with my computer, but my laptop is getting the answer.
My code looks like this:
Server:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server, { log: false });
var socket = socket;
io.sockets.on('connection', function (socket_) {
socket = socket_;
socket.on('dl_me', function (result) {
downloadTrack(result, result.song_uri);
if (typeof callback == 'function' ) {
callback({
success: success
});
}
});
});
var downloadTrack = function(result, uri) {
socket.emit('gotodownload', {
id: generated_number
});
}
Client:
var socket = io.connect( window.location.href );
socket.on('gotodownload', function(result) {
var linktodl = window.location.host + '/getme/' + result.id;
document.getElementById('dlbutton').innerHTML = 'Download!'
});
It's not the complete code, but every relevant socket.io part.
Try passing the socket object to your downloadTrack function:
// Add an argument for the socket object.
var downloadTrack = function(socket, result, uri) {
socket.emit('gotodownload', {
id: generated_number
});
}
And modify the code inside dl_me event to call the function like:
socket.on('dl_me', function (result) {
// Pass the socket to the function.
downloadTrack(socket, result, result.song_uri);
// ...
});

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
});

Parsing JSON url with NODE.JS and keeping it up to date with SOCKET.IO

I am very new to node.js and socket.io and I am trying to figure out how to read a JSON array from an external url, then parse it and display on the main page. Then I believe I use socket.io to keep that connection open and keep the JSON object up to date when a change occurs.
This is what I have so far for node.js.
var http = require("http");
var fs = require('fs');
var options = 'http://api.trakt.tv/user/watching.json/APIKEY/USERNAME';
var server = http.createServer(function(request, response){
console.log('Connection');
http.get(options, function(res){
var data = '';
res.on('data', function (chunk){
data += chunk;
});
res.on('end',function(){
var obj = JSON.parse(data);
console.log( obj );
})
});
response.end();
});
server.listen(8888);
When I connect to localhost:8888 I see the console show up with "connection" and then the console logs the contents of the JSON object. This is as far as I have managed to get. I would appreciate and help and pointers on how to get that JSON object displayed and styled on my index page and keep it up to date
TIA
Mark
Okay, now that I understand the problem, here is my answer. It's going to be a bit advice laden, as there is no true "right way" to do what you want. All we can be assured if is that yes, you are going to want to use WebSockets (or in this case socket.io, which can emulate websockets on older browsers).
Your current pull code is probably fine, though you're going to want to tweak that code to run on a timeout so that the latest JSON is pulled every so often. In addition, we want to keep the various moving parts of this seperate: Reading from the API/writing the cache, listening to the cache, and then feeding the cache out to connected clients:
var http = require("http");
var fs = require('fs');
var url = 'http://api.trakt.tv/user/watching.json/APIKEY/USERNAME';
var cacheFile = '/path/to/cachefile';
var connectedSockets = [];
function fetchJson() {
http.get(url, function(res) {
body = '';
res.on('data', function(data) {
body += data;
});
res.on('end', function() {
fs.writeFileSync(cacheFile, body);
setTimeout(fetchJson, 1000); // Fetch it again in a second
});
})
}
fetchJson(); // Start fetching to our JSON cache
// Start watching our cache file
fs.watch(cacheFile, function(event, filename) {
if(event == 'change') {
fs.readFile(cacheFile, function(data) {
connectedSockets.forEach(function(socket) {
socket.emit('data', JSON.parse(data));
});
});
}
});
// Now setup our socket server
var io = require('socket.io').listen(8888);
io.sockets.on('connection', function(socket) {
connectedSockets.push(socket);
});
I don't handle disconnected here (you'll want to remove disconnected or err'ed sockets from the connectedSockets list), and I didn't actually run this...but it should give you an idea of where to head.
On the client, it should be a matter of simply:
var socket = io.connect('http://localhost:8888');
socket.on('data', function (data) {
// Data will contain your JSON object, do your DOM manip here
});

Http request with node?

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);
});
});

Categories