In http://nodejs.org/docs/v0.4.7/api/http.html#http.request
There is an example that fetches some web content, but how does it save the content to a global variable? It only accesses stuff the function.
If look closely at the example, that HTTP request is used to POST data to a location. In order to GET web content, you should use the method GET.
var options = {
host: 'www.google.com',
port: 80,
method: 'GET'
};
The HTTP response is available in the on-event function inside the callback-function which is provided as the parameter for the constructor.
var req = http.request(options, function(res)
{
res.setEncoding('utf8');
var content;
res.on('data', function (chunk)
{
// chunk contains data read from the stream
// - save it to content
content += chunk;
});
res.on('end', function()
{
// content is read, do what you want
console.log( content );
});
});
Now that we have implemented the event handlers, call request end to send the request.
req.end();
Related
const https = require('https');
var postData = JSON.stringify({
'msg' : 'Hello World!'
});
let url;
url = "someurl2228.com";//dummy/random url (have removed actual url)
var options = {
hostname: url,
path: '/file/download/b8d61eff5314ac1ac982e5dbb9630f83',
method: 'GET',
headers: {myheader:"somedata"}
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
res.on('end',()=>{
console.log('********************END********');
});});
req.on('error', (e) => {
console.error(e);});
req.write(postData);
req.end();
I have removed actual urls. that is some just random url in my code above.
From my code I am using https module to call a external rest api which in response sends me a xlsx file.
I want to read the file (without saving will be great).
Now, when I use Postman's Send button to call that external api I receive a unicode chracters in respose tab.
But when I use Postman's Send and Download button to call that external api I can get the xlsx file to save.
Now, I am able to replicate same unicode as in I am receiving with Postman's Send button in my NodeJS code using https module but don't know what to do next.
I want to read the xlsx file's data for further task.
Want to read the xlsx file's data without saving it to do further task.
Also Adding a snippet of my excel
You could collect the result as a buffer and then pass the result to the XLSX's .read method (which will then read it in memory).
Try this:
var req = http.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
// store buffer here
let chunks = [];
res.on('data', (d) => {
chunks.push(d);
});
res.on('end', () => {
console.log('********************END********');
// feed buffer to `.read` method
const workbook = require('xlsx').read(chunks, {type: 'buffer'});
console.log('No more data in response.\nDo something with the workbook:\n\n', workbook);
});
});
I am trying to create http get request from node, to get information from youtube URL. When I click it in browser I get json response but if I try it from node, I get ssl and other types of error. What I have done is,
this.getApiUrl(params.videoInfo, function (generatedUrl) {
// Here is generated URL - // https://www.googleapis.com/youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus
console.log(generatedUrl);
var req = http.get(generatedUrl, function (response) {
var str = '';
console.log('Response is ' + response.statusCode);
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
});
req.end();
req.on('error', function (e) {
console.log(e);
});
});
I get this error
{
"error": {
"message": "Protocol \"https:\" not supported. Expected \"http:\".",
"error": {}
}
}
When I make it without https I get this error,
Response is 403
{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL is required to perform this operation."}],"code":403,"message":"SSL is required to perform this operation."}}
You need to use the https module as opposed to the http module from node, also I would suggest one of many http libraries that provide a higher level api such as wreck or restler which allow you to control the protocol via options as opposed to a different required module.
Your problem is obviously accessing content served securely with http request hence, the error. As I have commented in your question, you can make use of https rather than http and that should work but, you can also use any of the following approaches.
Using request module as follow:
var url = "https://www.googleapis.com/youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus";
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
Using https module you can do like below:
var https = require('https');
var options = {
hostname: 'www.googleapis.com', //your hostname youtu
port: 443,
path: '//youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus',
method: 'GET'
};
//or https.get() can also be used if not specified in options object
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
You can also use requestify module and
var url = "https://www.googleapis.com/youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus";
requestify.get(url).then(function(response) {
// Get the response body
console.log(response.body);
});
superagent module is another option
var url = "https://www.googleapis.com/youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus";
superagent('GET', url).end(function(response){
console.log('Response text:', response.body);
});
Last but not least is the unirest module allow you to make http/https request as simple as follow:
var url = "https://www.googleapis.com/youtube/v3/videos?key=AIzaSyAm_1TROkfNgY-bBuHmSaletJhVQmkycJc&id=_H_r9qVrf24&part=id%2Csnippet%2CcontentDetails%2Cplayer%2Cstatistics%2Cstatus";
unirest.get(url).end(function(res) {
console.log(res.raw_body);
});
There might be more options out there. Obviously you need to load the modules using require before using it
var request = require('request');
var https = require('https');
var requestify = require('requestify');
var superagent = require('superagent');
var unirest = require('unirest');
I provided extra details, not only to answer the question but, also to help others who browse for similiar question on how to make http/https request in nodejs.
Following the documentation of the Github API to create an authorization for a NodeJS app.
I have the following code:
var _options = {
headers: {
'User-Agent': app.get('ORGANISATION')
},
hostname: 'api.github.com'
};
var oauth2Authorize = function () {
var path = '/authorizations?scopes=repo';
path += '&client_id='+ app.get('GITHUB_CLIENT_ID');
path += '&client_secret='+ app.get('GITHUB_CLIENT_SECRET');
path += '¬e=ReviewerAssistant';
_options.path = path;
_options.method = 'POST';
var request = https.request(_options, function (response) {
var data = "";
response.on('data', function (chunk) {
data += chunk;
});
response.on('end', function () {
console.log(data);
});
});
request.on('error', function (error) {
console.log('Problem with request: '+ error);
});
};
And all I get is:
408 Request Time-out
Your browser didn't send a complete request in time.
Doing a GET request works though.
http.request() doesn't immediately send the request:
With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.
It opens the underlying connection to the server, but leaves the request incomplete so that a body/message can be sent with it:
var request = http.request({ method: 'POST', ... });
request.write('data\n');
request.write('data\n');
request.end();
And, regardless of whether there's anything to write() or not, you must call end() to complete the request and send it in its entirety. Without that, the server will eventually force the open connection to close. In this case, with a 408 response.
Basically I receive the values from a form with the function event:
var formData="";
req.on('data', function (chunk){
formData += chunk;
});
And I send those values again in another http.request:
req.on('end', function (){
var options = { port: conf.port, path: req.path,
host: conf.host, method: req.method , headers: req.headers};
authReq = http.request(options,
function (response){...});
authReq.write(formData);
authReq.end();
});
What I want is to add more data to the form receive from the previously form, like for example something like this:
var formData="client_id=XXX&client_secret=XXX&";
req.on('data', function (chunk){
formData += chunk;
});
But this is not working, after made the authReq.write(formData); looks like the data send is empty or wrong.... any suggestion ?
In the second request, the variable formData filled in the first request, will be empty.
You might need to use a session. (http://expressjs-book.com/forums/topic/express-js-sessions-a-detailed-tutorial/)
Also, from the looks of your code snippets, I suggest you look into http://passportjs.org/ for authentication :)
How can we stop the remaining response from a server -
For eg.
http.get(requestOptions, function(response){
//Log the file size;
console.log('File Size:', response.headers['content-length']);
// Some code to download the remaining part of the response?
}).on('error', onError);
I just want to log the file size and not waste my bandwidth in downloading the remaining file. Does nodejs automatically handles this or do I have to write some special code for it?
If you just want fetch the size of the file, it is best to use HTTP HEAD, which returns only the response headers from the server without the body.
You can make a HEAD request in Node.js like this:
var http = require("http"),
// make the request over HTTP HEAD
// which will only return the headers
requestOpts = {
host: "www.google.com",
port: 80,
path: "/images/srpr/logo4w.png",
method: "HEAD"
};
var request = http.request(requestOpts, function (response) {
console.log("Response headers:", response.headers);
console.log("File size:", response.headers["content-length"]);
});
request.on("error", function (err) {
console.log(err);
});
// send the request
request.end();
EDIT:
I realized that I didn't really answer your question, which is essentially "How do I terminate a request early in Node.js?". You can terminate any request in the middle of processing by calling response.destroy():
var request = http.get("http://www.google.com/images/srpr/logo4w.png", function (response) {
console.log("Response headers:", response.headers);
// terminate request early by calling destroy()
// this should only fire the data event only once before terminating
response.destroy();
response.on("data", function (chunk) {
console.log("received data chunk:", chunk);
});
});
You can test this by commenting out the the destroy() call and observing that in a full request two chunks are returned. Like mentioned elsewhere, however, it is more efficient to simply use HTTP HEAD.
You need to perform a HEAD request instead of a get
Taken from this answer
var http = require('http');
var options = {
method: 'HEAD',
host: 'stackoverflow.com',
port: 80,
path: '/'
};
var req = http.request(options, function(res) {
console.log(JSON.stringify(res.headers));
var fileSize = res.headers['content-length']
console.log(fileSize)
}
);
req.end();