Get Response URL from GET Request - javascript

Using the request node library to make GET requests and and wondering how to grab the URL from the response returned.
Something like
var request = require('request');
request('http://www.somewebsite.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // grab the url here
}
})
assuming the response returned is not www.somewebsite.com but a redirect.

Start at the documentation. Search it for redirect and you'll find:
followRedirect - follow HTTP 3xx responses as redirects (default: true). This property can also be implemented as function which gets response object as a single argument and should return true if redirects should continue or false otherwise.
Note the status code. You only get the 200 after the redirect has been followed.
Therefore:
var request = require('request');
request({
uri: 'http://google.com',
followRedirect: function(response) {
console.log("Redirecting to " + response.headers.location);
return true;
}
},
function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
}
);

Related

SyntaxError: Unexpected token e in JSON at position 1 with JSON.parse()

I am trying to use openweathermap.org weather api, I am getting the data but having trouble parsing it.
Here's my code:
request("https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric&callback=test", function(error, response, body) {
if (!error && response.statusCode == 200) {
var parsedData = JSON.parse(body);
console.log(typeof body);
}
});
console.log(typeof body); returns string so I just can't figure out what 's the problem.
You are looking for this - the URL is JSONP so it expects a function called test and no need to parse
<script>
const test = data => console.log(data);
</script>
<script src="https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric&callback=test"></script>
Alternatively remove the callback - here using fetch:
fetch("https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric")
.then(response => response.json())
.then(data => console.log(data));
Or Axios
axios.get('https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric')
.then(response => console.log(response.data));
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
This worked for me. Just set object for the first argument with url and json property. set json:true. Setting to true will handle the parsing for you :)
const request = require('request');
const url = "https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric";
request({ url: url, json: true }, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
As #mplungjan pointed out. That's a JSONP url.
Remove &callback=test at the end of your URL then you don't have to deal with JSONP and you can work with it like normal.
Since you are using an API which has a callback function return as response. It is not JSON but JSONP (JSON with Padding).
Your code will work just fine if you remove the callback parameter from URL.
request("https://api.openweathermap.org/data/2.5/weather?lat=30.4831&lon=76.595&appid=7beb6de85d3f3a28dabda1015684562f&units=metric", function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(response);
}
});
For further reading about JSONP, You can refer this.

Google Cloud Functions - Nodejs error , forever loading

const request = require('request');
exports.helloWorld = function helloWorld(req, res) {
var headers = {
'scheme': 'https',
'authorization': 'Token 123',
'user-agent': 'mobile'
};
var options = {
url: 'https://url',
headers: headers
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
res.status(200).send(response.body);
}
}
request(options, callback);
};
I can submit a request without issue, but once i start doing a request with headers and options , i cant get it to work properly on Google Cloud Function.
Please advice on my mistake
Trigger type
: HTTP trigger
It's likely that an error is being returned from the call you're making using request, and since in the error case you don't end the function using res.end() or res.status(500).end(), Cloud Functions doesn't know if your function is done or not, so just runs it until a timeout is hit.
Try:
if (!error && response.statusCode == 200) {
console.log(body);
res.status(200).send(response.body);
} else {
console.log(error);
res.status(500).send(error);
}
You should get a response back without the Cloud Function hanging.

request node module not giving html

I am using request nodejs module to get html for a website as below:
var request = require('request');
request("http://www.thenewschool.org/", function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("body>>>>>>>>>>");
} else {
console.log("error>>>>>>>>>"+error);
console.log("response statusCode>>>>>>>>>"+response.statusCode);
console.log("response body>>>>>>>>>"+response.body);
}
})
and this gives me this output
error>>>>>>>>>null
response statusCode>>>>>>>>>403
response body>>>>>>>>>Sorry, this request has been blocked due to an
invalid user agent.
This is passing for most of the cases, but fails in this case, can someone help me to solve this.
You just have to pass the user-agent in the headers (because the URL requires it), like:
var options = {
headers: {'user-agent': 'node.js'}
}
request("http://www.thenewschool.org/", options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("body>>>>>>>>>>" + body);
} else {
console.log("error>>>>>>>>>"+error);
console.log("response statusCode>>>>>>>>>"+response.statusCode);
console.log("response body>>>>>>>>>"+response.body);
}
})
well you are receiving an HTTP 403 error code : Access Is Forbidden.
this probably means that your request has been "profiled" as "we don't want you here" :
this can be because your IP has been flagged
or because your are missing a header that would make your request look like the one of a real browser. Most probably the user-agent header given the body of the answer

Trying to send JSON response with Restify

I am trying to list all jobs with a certain tag on angel.co using their API with the current call
https://api.angel.co/1/tags/10/startups
and then trying to parse it and show in the browser using restify
var tagUrl = "https://api.angel.co/1/tags/10/startups"
request({
url: tagUrl,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body) // Print the json response
}
else console.log("error" + error)
})
I'm getting the console.log(body)-part to work, but when I am trying to send the response to the browser it doesn't show anything when I am trying to send it with
res.send('hello ' + req.params.name + body);
Should I parse or stringify it in some way ?
edit: This is the final code
function respond(req, res, next) {
var tag = req.params.tag;
var url = "http://api.angel.co/1/tags/"+tag+"/startups/?
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body) // Print the json response
res.send( req.params.name + JSON.stringify(body));
}
else console.log("error" + error)
})
Use stringify property of json,which converts the json format to string
JSON.stringify(body)

Protractor: Using result of an api call

I created a small api to generate test data on the fly. Each call creates a fresh user and returns the created data.
To load the data I use the package request:
var flow = protractor.promise.controlFlow();
var result = flow.execute(function() {
var defer = protractor.promise.defer();
request('http://localhost/test/recipe/person', function (error, response, body) {
if (!error && response.statusCode === 200) {
defer.fulfill(JSON.parse(body));
}
});
return defer.promise;
});
To make any use of the retrieved data I have to resolve the promise and proceed the test script inside a callback:
result.then(function(data) {
element(by.model('username')).sendKeys(data.person.email);
element(by.model('password')).sendKeys('test');
$('button[type="submit"]').click();
});
I don't like this callback handling and the possible hell it will lead to. Besides that, Protractor is so good in hiding this messy callback handling thingy. So, the question is:
How to use the result of an async call?
At the end I would like to perform code like the following:
var flow = protractor.promise.controlFlow();
var result = flow.execute(function() {...});
element(by.model('username')).sendKeys(result.person.email);
//...
Any ideas?
You can either make the http request synchronous - In most cases that's a bad thing to do.
Or, you can insert the callback into the execute function:
var flow = protractor.promise.controlFlow();
var result = flow.execute(function() {
var defer = protractor.promise.defer();
request('http://localhost/test/recipe/person', function (error, response, body) {
if (!error && response.statusCode === 200) {
defer.fulfill(JSON.parse(body));
}
});
defer.promise.then(function(data) {
element(by.model('username')).sendKeys(data.person.email);
element(by.model('password')).sendKeys('test');
$('button[type="submit"]').click();
});
return defer.promise;
});
but result will stay a promise.
It worked for me:
var request = require('request');
var options = {
method: 'POST',
url: 'http://testurl.com/endpoint/test/',
headers: {'id': 'ABCD',
'sessionid': 'dummyId',
'Accept': 'application/json',
'Accept-Language': 'en-us'
},
body: '{ "pay_load": [] }'
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
console.log(body);
console.log(info);
}
}
request(options, callback);

Categories