I recently start learning node.js,
In node.js https module I make a server request with https.get(); and i console.dir(res.header) this give me the response header, but when I try to console.dir(res.body) this give me undefined;
I did some investigation on the internet, and I have seen that I need to call data event to log the body. It's make me confused, why can't I log body directly, and the data format for header is string and for body is buffer?
Here are some examples of using the https.request method (same as get), they should show you some ways to use the method. These examples use the httpbin.org site, a very useful one for playing around with this kind of code.
const https = require ('https');
// Example 1
// This will return the IP address of the client
var request = https.request({ hostname: "httpbin.org", path: "/ip" }, (res) => {
console.log('/ip', res.statusCode);
res.on('data', (d) => {
console.log('/ip response: ', d.toString());
});
});
request.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
request.end();
// Example 2
// This will return some simple data about the get request
request = https.request({ hostname: "httpbin.org", path: "/get"}, (res) => {
console.log('/get', res.statusCode);
res.on('data', (d) => {
console.log('/get response: ', d.toString());
});
});
request.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
request.end();
// Example 3
var data = JSON.stringify({firstName: 'Mike', secondName: 'Jones'});
// This will return the data passed request
request = https.request({ hostname: "httpbin.org", path: "/anything", method: "GET", headers:
{ 'Content-Length': data.length, 'Content-Type': 'application/json' }}, (res) => {
console.log('/anything', res.statusCode);
res.on('data', (d) => {
console.log('/anything response: ', d.toString());
});
});
request.write(data);
request.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
request.end();
Related
I am learning node, but can't figure out how to send a POST request with a string.
Here is my code:
const h = require('https');
h.post("https://VLang.johnstev111.repl.co", "print('test')")
This should do pretty much what you wish, we log the response and any errors.
I've set the content-type to 'text/plain', and you can change the data by setting the postData variable to whatever you wish.
const https = require('https');
// Put your post data here
const postData = "print(40 + 2)";
const options = {
hostname: 'VLang.johnstev111.repl.co',
method: 'POST',
headers: {
'Content-Length': postData.length
}
};
const req = https.request(options, (res) => {
console.log('Response: status:', res.statusCode);
console.log('Response: headers:', res.headers);
res.on('data', (d) => {
process.stdout.write("Response: " + d);
});
});
req.on('error', (e) => {
console.error("An error occurred:", e);
});
req.write(postData);
req.end();
How do I return the response value, access_token, to a variable for use elsewhere? It yields undefined if I try to log its value outside of res.on('data') listener.
const http = require('http');
const authGrantType = 'password';
const username = '[The username]';
const password = '[The password]';
const postData = `grant_type=${authGrantType}&username=${username}&password=${password}`;
const options = {
hostname: '[URL of the dev site, also omitting "http://" from the string]',
port: 80,
path: '[Path of the token]',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
};
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`); // Print out the status
console.log(`HEADERS: ${JSON.stringify(res.headers)}`); // Print out the header
res.setEncoding('utf8');
res.on('data', (access_token) => {
console.log(`BODY: ${access_token}`); // This prints out the generated token. This piece of data needs to be exported elsewhere
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// write data to request body
req.write(postData);
req.end();
The token value is logged to the console by the line that reads: console.log(`BODY: ${access_token}`); The issue is with trying to extract this value to be used elsewhere. Rather than having to encapsulate every new function with an HTTP call inside the other call that was required to supersede it and provide it with a response before it could continue. It's sort of enforcing synchronicity in NodeJS.
You should encapsutale your code with a promise
return new Promise((resolve, reject) => {
const req = http.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', (d) => {
resolve(d);
})
});
req.on('error', (e) => {
reject(e);
});
req.write(data);
req.end();
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
[EDIT]
I figured it out. The code ends up like this:
//getTrelloJSON.js
var request = require('request');
'use strict';
function getProjJSON(requestURL, callback){
request.get({
url: requestURL,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
} else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
} else {
callback(data);
}
});
}
module.exports.getProjJSON = getProjJSON;
And
//showData.js
var getJSON = require('./getTrelloJSON');
getJSON.getProjJSON('https://trello.com/b/saDpzgbw/ld40-gem-sorceress.json', (result) => {
var lists = result.lists;
console.log(lists);
});
I run node showData.js and it gets the json and then I can manipulate it as needed. I printed just to show it works.
[EDIT END]
I'm new to node.js and I am facing a noob problem.
This code is supposed to request a JSON from a public trello board and return an object with a section of trello's json (lists section).
The first console.log() does not work but the second does.
How do I make it wait for the completion of getProjJSON() before printing it?
var request = require('request');
'use strict';
//it fails
console.log(getProjJSON('https://trello.com/b/saDpzgbw/ld40-gem-sorceress.json'));
function getProjJSON(requestURL){
request.get({
url: requestURL,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
} else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
} else {
//it works
console.log(data.lists);
return data.lists;
}
});
}
Node.js is all about callbacks.
And here you just not register the callbacks for data.
var client = require('http');
var options = {
hostname: 'host.tld',
path: '/{uri}',
method: 'GET', //POST,PUT,DELETE etc
port: 80,
headers: {} //
};
//handle request;
pRequest = client.request(options, function(response){
console.log("Code: "+response.statusCode+ "\n Headers: "+response.headers);
response.on('data', function (chunk) {
console.log(chunk);
});
response.on('end',function(){
console.log("\nResponse ended\n");
});
response.on('error', function(err){
console.log("Error Occurred: "+err.message);
});
});
or here is a full example, hope this solve your problem
const postData = querystring.stringify({
'msg' : 'Hello World!'
});
const options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
const req = http.request(options, (res) => {
console.log(`res_code: ${res.statusCode}`);
console.log(`res_header: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`res_data: ${chunk}`);
});
res.on('end', () => {
console.log('end of response');
});
});
req.on('error', (e) => {
console.error(`response error ${e.message}`);
});
//write back
req.write(postData);
req.end();
It's giving unauthorized as result error even when I pass the bearer token in Node.js application.
function getUser(authData){
var postData = querystring.stringify({ authorization: authData });
var options = {
host: 'pole.auth0.com',
method: 'GET',
path: '/userinfo'
};
//make request
httpsRequest(postData, options)
.then(function(result) {
// success
res.status(201).send({ 'success': true });
}, function(err) {
res.status(500).send({ 'success': false, 'reasonCode': "Internal error." });
});
};
Helper function:
function httpsRequest (data, options) {
return new Promise(function (resolve, reject) {
var req = https.request(options, function (res) {
var result = '';
console.log(options);
res.on('data', function (chunk) {
result += chunk;
});
res.on('end', function () {
console.log("https end result - " + result);
resolve(result);
});
res.on('error', function (err) {
reject(err);
})
});
// req error
req.on('error', function (err) {
reject(err);
});
//send request witht the postData form
req.write(data);
req.end();
});
}
The authData parameter has a string value like Bearer [token]. I'm using https.request to make the api request
Is there anything wrong on the code?
According to the /userinfo endpoint documentation you should be performing a GET HTTP request instead of a POST and additionally, you need to pass the access token in the Authorization header.
Update:
The problem is in how you're trying to pass the token in the authorization header.
You did not mentioned what you were using as HTTP client, but here's some sample code using request-promise as the Node HTTP client; this works fine.
var rp = require('request-promise');
var options = {
uri: 'https://[YOUR_TENANT].auth0.com/userinfo',
headers: {
'Authorization': 'Bearer [YOUR_ACCESS_TOKEN]'
}
};
rp(options)
.then(function (info) {
console.log('User information:', info);
})
.catch(function (err) {
// API call failed...
});
Update 2:
With Node.js built-in HTTP client:
const https = require('https');
var options = {
hostname: '[YOUR_TENANT].auth0.com',
port: 443,
path: '/userinfo',
method: 'GET',
headers: {
'Authorization': 'Bearer [YOUR_ACCESS_TOKEN]'
}
};
var req = https.request(options, (res) => {
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.end();
req.on('error', (e) => {
console.error(e);
});
Again, the vital part is on how to pass the token in the correct header.
I am getting a "socket hang up" error while doing a post request. I am not able to resolve it.
sparqlQ = getSPARQLPrefix() + query_string;
console.log(sparqlQ)
var options = {
host: process.env['SESAME_HOST'],
port: process.env['SESAME_PORT'],
method: 'POST',
path:
'/openrdf-sesame/repositories/myReo?update=' +
encodeURIComponent(sparqlQ) +
'&content-type=application/sparql-results+json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/sparql-results+json',
},
};
var req = http.request(options, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('error', function (error) {
console.log(error)
});
res.on('end', function () {
console.log(data)
req.end();
callback(null);
});
}).on('error', function(e) {
console.alert("Error getting sesame response [%s]", e.message);
req.end();
callback(e.message);
return
});
What am I doing wrong? Please help!
Two things to mention here.
You are not calling req.end() on your http request.
refer this documentation on the http module of node.js.
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.
on the req.error event you are calling console.alert which i think should be console.log
Here is a sample code
http = require("http");
var options = {
host: "localhost",
port: 80,
method: 'POST'
};
var req = http.request(options, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('error', function (error) { });
res.on('end', function () {
console.log(data)
req.end();
console.log(null);
});
}).on('error', function(e) {
console.log("Error getting sesame response [%s]", e.message);
req.end();
console.log(e.message);
return
});
req.end();