I am needing to find a way to get a response as a result of a https post request. So far from what I hae found that is only provided in the call back function, which does not include the result after data is written to the request and is ended as shown below:
**Note: the code below would be wrapped inside a "app.post" method.
const https = require("https");
var url = "https://someurl.com";
var options = {option1: "some option"}
var jsonData = {data1: "some data"};
const request = https.request(url, options, function (repsonse) {
// HERE THE STATUS CODE ONLY CAPTURES IF THE RESOURCE WAS AVAILABLE
// NOT IF THE REQUEST WAS SUCCESSFUL
console.log(response.statusCode);
});
request.write(jsonData);
request.end();
After the "request.end()" code i need to be able to get the status code returned from the request to determine if the actual request was successful. I would want to do something like this:
if (response.statusCode !== 200) {
res.sendFile(__dirname + "/failure.html");
}
else {
res.sendFile(__dirname + "/success.html");
}
The if statement should run after request.end() to determine if the actual request was successful. This is standard for using API frameworks such as Flask-Python, but I can't seem to find a way to catch this in express.js. Any help would be appreciated.
https.request works asynchronously. Whether the request is successful or not cannot be determined synchronously after the request.end(), but only in the callback function (where you can evaluate response.statusCode) or in the error event (if the request could not be made at all, for example because the server was unreachable).
const request = https.request(url, options, function (response) {
console.log(response.statusCode);
if (response.statusCode !== 200)
res.sendFile(__dirname + "/failure.html");
else
res.sendFile(__dirname + "/success.html");
});
request.on("error", function(err) {
console.error(err);
res.sendFile(__dirname + "/failure.html");
});
request.write(jsonData);
request.end();
Related
I am experimenting with the softlayer-client api wrapper in my Node Express application. My goal is to update the VPN password of a User_Customer by calling the updateVpnPassword method on a specific user.
I can construct a call to achieve a VPN password update using request, but I'm not sure it's the best way to achieve the desired result.
Can the softlayer-client module be used to make an similar call to this:
function updateVpnPassword(req, res, next) {
// Construct URL to update VPN
myURL = 'https://' + <userIDAdmin> + ':' + <apiKeyAdmin> + '#api.softlayer.com/rest/v3/SoftLayer_User_Customer/' + <softLayerID> + '/updateVpnPassword/' + <newPassword> + '.json';
request.get({url: myURL}, function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
next();
}
My initial attempts have been to try variations on this:
function updateVpnPassword(req, res, next) {
// Assuming var client = new SoftLayer();
client
.auth(<userIDAdmin>, <apiKeyAdmin>)
.path('User_Customer', <softLayerID>,'updateVpnPassword')
.parameters(<newPassword>)
.put(function(err,result){
console.log(result);
if (err) {
next(err); // Pass errors to Express.
}
else {
// update successful
}
});
next();
}
But the console log gives an error response like
{ message: { error: 'Internal Error', code: 'SoftLayer_Exception_Public' } }.
I expect a TRUE or FALSE response, to indicate the whether the update is successful.
A similar python client can be found here but I require an implementation in JS.
I'm not familiar with nodejs but I installed the package softlayer-node and run your second code and it worked.
I also created the following script and I got TRUE
var username = 'set me';
var apikey = 'set me';
var userId = 1111111;
var SoftLayer = require('softlayer-node');
var client = new SoftLayer();
client
.auth(username, apikey)
.path('User_Custome', userId, 'updateVpnPassword')
.parameters('P#ssword123')
.put()
.then(function(result) {
console.log(result);
}, function(error) {
console.log(error);
});
node command:
$ node updateVpnPassword.js
true
Did you tried by sending that request using curl or any other REST client like postman?
If you get the same error then I recommend you submit a ticket and provide information like the id of users you are trying to update the vpn password and the user with which you are sending the request.
Basically, I'm trying to get Access Token from Facebook in my callBack GET method. Below is my code.
getAccessToken is not called at all. What's the right way to implement it?
app.get('/fbcallback', function(req, res) {
var code = req.query.code;
var getAccessToken = 'https://graph.facebook.com/v2.12/oauth/access_token?'+
'client_id='+client_id+
'&redirect_uri='+redirect_uri+
'&client_secret='+client_secret+
'&code='+code;
app.use(getAccessToken, function(req, res) {
console.log('Token Call');
});
});
You should not use app.use inside get the call.
You must be trying to do something like below. Inside get call make another get call for getting token.
var request = require('request');
app.get('/fbcallback', function (req, res) {
var code = req.query.code;
var getAccessToken = 'https://graph.facebook.com/v2.12/oauth/access_token?' +
'client_id=' + client_id +
'&redirect_uri=' + redirect_uri +
'&client_secret=' + client_secret +
'&code=' + code;
request(getAccessToken, 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 the HTML for the Google homepage.
});
});
I have an app and I would like to use it as a proxy. Code looks like this
I am using request npm.
app.all('*', function(req, res){
console.log(req.url); //lower case
console.log(req.url.substr(0, 5));
var alteredRequest;
if (req.url.substr(0,5) == '/pro/') {
var requestedURL = req.url.substr(5);
console.log(requestedURL);
if( (requestedURL.substr(0, 7) != 'http://') || (requestedURL.substr(0, 8) != 'https://') ){
alteredRequest = "http://" + requestedURL;
}
request(alteredRequest, 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
res.send(response);
})
}
})
When I call res.send(response) at the end I get the response as a body, and all the headers exc are taken to the html body logged to the screen. Rather than that, I would like to send it as a real response with all the headers and cookies. How do I achieve it? thank you for helping.
To do more demonstration, the response (from google.com) starts like this, but it's on the screen! not the real headers and statusCode:
{"statusCode":200,"body":"<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org/WebPage\" lang=\"tr\"><head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\"><meta content=\"/images/branding/googleg/1x/googleg_standard_color_128dp.png\" itemprop=\"image\"><title>Google</title><script nonce=\"fzz0lJtfXqp5SuC6mvodsw==\">(function(){window.google=
it's a really bad way to do redirects. You should be using
res.redirect and req.protocol to do that
if (req.url.substr(0,5) == '/pro/') is perhaps the most hideous way of catching a route I've ever seen. This is what app.get('/', ...) is designed for.
But to answer your question, here's a working example
const express = require("express");
const request = require("request");
const app = express();
app.all('*', (req, res) => {
const newUrl = 'http://www.google.com'; //replace with your url altering code
return request(newUrl)
.on('response', function(response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type'])
})
.on('error', function(err) {
console.log(err)
})
.pipe(res);
});
app.listen(9000);
I have a simple node Express app that has a service that makesa call to a node server. The node server makes a call to an AWS web service. The AWS simply lists any S3 buckets it's found and is an asynchronous call. The problem is I don't seem to be able to get the server code to "wait" for the AWS call to return with the JSON data and the function returns undefined.
I've read many, many articles on the web about this including promises, wait-for's etc. but I think I'm not understanding the way these work fully!
This is my first exposer to node and I would be grateful if somebody could point me in the right direction?
Here's some snippets of my code...apologies if it's a bit rough but I've chopped and changed things many times over!
Node Express;
var Httpreq = new XMLHttpRequest(); // a new request
Httpreq.open("GET","http://localhost:3000/listbuckets",false);
Httpreq.send(null);
console.log(Httpreq.responseText);
return Httpreq.responseText;
Node Server
app.get('/listbuckets', function (req, res) {
var bucketData = MyFunction(res,req);
console.log("bucketData: " + bucketData);
});
function MyFunction(res, req) {
var mydata;
var params = {};
res.send('Here are some more buckets!');
var request = s3.listBuckets();
// register a callback event handler
request.on('success', function(response) {
// log the successful data response
console.log(response.data);
mydata = response.data;
});
// send the request
request.
on('success', function(response) {
console.log("Success!");
}).
on('error', function(response) {
console.log("Error!");
}).
on('complete', function() {
console.log("Always!");
}).
send();
return mydata;
}
Use the latest Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make HTTP calls. It has built-in support with Promise.
fetch('http://localhost:3000/listbuckets').then(response => {
// do something with the response here
}).catch(error => {
// Error :(
})
I eventually got this working with;
const request = require('request');
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
parseString(body, function (err, result) {
console.log(JSON.stringify(result));
});
// from within the callback, write data to response, essentially returning it.
res.send(body);
}
else {
// console.log(JSON.stringify(response));
}
})
I'm working on testing my node.js code with Zombie.js. I have the following api, which is in POST method:
/api/names
and following code in my test/person.js file:
it('Test Retreiving Names Via Browser', function(done){
this.timeout(10000);
var url = host + "/api/names";
var browser = new zombie.Browser();
browser.visit(url, function(err, _browser, status){
if(browser.error)
{
console.log("Invalid url!!! " + url);
}
else
{
console.log("Valid url!!!" + ". Status " + status);
}
done();
});
});
Now, when I execute the command mocha from my terminal, it gets into browser.error condition. However, if I set my API to get method, it works as expected and gets into Valid Url (else part). I guess this is because of having my API in post method.
PS: I don't have any Form created to execute the queries on button click as I'm developing a back-end for mobile.
Any help on how to execute APIs with POST method would be appreciated.
Zombie is more for interacting with actual webpages, and in the case of post requests actual forms.
For your test use the request module and manually craft the post request yourself
var request = require('request')
var should = require('should')
describe('URL names', function () {
it('Should give error on invalid url', function(done) {
// assume the following url is invalid
var url = 'http://localhost:5000/api/names'
var opts = {
url: url,
method: 'post'
}
request(opts, function (err, res, body) {
// you will need to customize the assertions below based on your server
// if server returns an actual error
should.exist(err)
// maybe you want to check the status code
res.statusCode.should.eql(404, 'wrong status code returned from server')
done()
})
})
it('Should not give error on valid url', function(done) {
// assume the following url is valid
var url = 'http://localhost:5000/api/foo'
var opts = {
url: url,
method: 'post'
}
request(opts, function (err, res, body) {
// you will need to customize the assertions below based on your server
// if server returns an actual error
should.not.exist(err)
// maybe you want to check the status code
res.statusCode.should.eql(200, 'wrong status code returned from server')
done()
})
})
})
For the example code above you will need the request and should modules
npm install --save-dev request should