Get UTF-8 html content with Node's http.get - html

I'm trying to pull the html content of a given url and the origin content encoding is utf-8. I get the html of the page but the text whitin the html elemnts are returned in bad format (question marks).
This is what I do:
var parsedPath = url.parse(path);
var options = {
host: parsedPath.host,
path: parsedPath.path,
headers: {
'Accept-Charset' : 'utf-8',
}
}
http.get(options, function (res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on("end", function () {
console.log(data);
});
}).on("error", function () {
callback(null);
});
How can I enforce the encoding of the returned data?
Thanks

Use the setEncoding() method like this:
http.get(options, function (res) {
res.setEncoding('utf8');
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on("end", function () {
console.log(data);
});
});

Related

Nodejs getting a incomplete response body

I am using http module to send a request to api. So my response body is very large, and I am getting incomplete and when trying to parse to javascript object I am getting an error, that the json is not valid.
Here is my code.
function sendPostRequest(method, url, data, callback) {
if (typeof data === 'undefined') {
data = {};
}
var data = querystring.stringify(data);
var post_options = {
host: API.Host,
port: API.Port,
path: API.Prefix + url,
method: method,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + API_USER.token
}
};
var post_req = http.request(post_options, function (res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
callback(chunk);
});
});
// post the data
post_req.write(data);
post_req.end();
}
sendPostRequest('GET', 'user/get_accounts', data, function (res) {
res = JSON.parse(res);
mainWindow.webContents.send('user:account', res);
return;
}, true);
Please help to solve this problem! Thanks!
If the data is large and it's provided in chunks(incomplete json) you might have better luck with:
var post_req = http.request(post_options, function (res) {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
callback(rawData);
});
});

$http.post within a $http.post, return response is not updated directly

I have a function, it has a $http.post for login purpose. If success, another $http.post will call a php file that fetches data from database. The problem is that, when I am trying to load the data from localStorage it returns me null. Why is it so?
$scope.loginUser = function ()
{
var data =
{
username: $scope.loginInfo.username,
password: $scope.loginInfo.password
}
$http.post("endpoints/login.php", data).success(function(response)
{
if(response==="ERROR")
{
//DONT DO ANYTHING
}
else
{
localStorage.setItem("token", JSON.stringify(response));
console.log("loginController: name is this " + localStorage);
fetchDataFunction(data);
$state.go("application");
//$state.go("application", result);
}
}).error(function(error)
{
console.error(error);
});
}
fetchDataFunction = function(data)
{
$http.post("endpoints/fetchData.php", data).success(function(response)
{
localStorage.setItem("data", JSON.stringify(response));
}).error(function(error)
{
console.error(error);
});
}
You can return the $http.post, which will return a promise, and then all your code will work in the correct order:
$scope.loginUser = function () {
login($scope.loginInfo).then(function (response) {
localStorage.setItem("token", JSON.stringify(response));
console.log("loginController: name is this " + localStorage.getItem("token"));
fetchDataFunction(data).then(function () {
localStorage.setItem("data", JSON.stringify(response));
console.log(localStorage.getItem("data"));
$state.go("application");
}).catch(function (error) {
console.error(error);
});
}).catch(function (response) {
console.error(error);
});
};
var login = function (user) {
return post("endpoints/login.php", user);
};
var fetchDataFunction = function (data) {
return post("endpoints/fetchData.php", data);
};
var post = function (url, data) {
var deferred = $q.defer;
$http.post(url, data).then(function (response) {
if (response === "ERROR") {
deferred.reject(response);
}
else {
deferred.resolve(response);
}
}).catch(function (error) {
deferred.reject(error);
});
return deferred;
};
Notes:
You will need to make sure you inject $q into your controller along with $http
You should use localStorage.getItem() when recalling information from the global object
You should use then/catch instead of success/error, as these are now depreciated: https://docs.angularjs.org/api/ng/service/$http

How do I return JSON in my Node.js proxy?

I had to proxy the requests to the Dota 2 API. After some research I found a way to do it in the API I am building using the MEAN stack. However, I can't figure out how to return the data from the request.
Here is my route in my node server code:
router.get('/api/allheros', function (req, res) {
Https.get('https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=FB900D42DC33F4B4FCC62F6C7779BE5D', function (res) {
var str = '';
console.log('Response is ' + res.statusCode);
res.on('data', function (chunk) {
str += chunk;
});
res.on('end', function () {
console.log(str); //This console logs all the heros correctly
});
});
});
The console log works but I need the data to be returned to the front end.
All you need to do is parse your result into a JSON Object and send it back using res.json(). Modify your code as follows,
router.get('/api/allheros', function (req, res) {
Https.get('https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=FB900D42DC33F4B4FCC62F6C7779BE5D', function (response) {
var str = '';
console.log('Response is ' + response.statusCode);
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
res.json(JSON.parse(str));
});
});
});
Note: The res in inner function had to be changed to response so that it doesn't mask the res parameter of outer function.

cors unexpected end of JSON input

I am parsing my json on end but I am still receiving this error.
'use strict';
const http = require('http');
const tools = require('./tools.js');
const server = http.createServer(function(request, response) {
console.log("received " + request.method + " request from " + request.headers.referer)
var body = "";
request.on('error', function(err) {
console.log(err);
}).on('data', function(chunk) {
body += chunk;
}).on('end', function() {
console.log("body " + body);
var data = JSON.parse(body); // trying to parse the json
handleData(data);
});
tools.setHeaders(response);
response.write('message for me');
response.end();
});
server.listen(8569, "192.168.0.14");
console.log('Server running at 192.168.0.14 on port ' + 8569);
Data being sent from the client:
var data = JSON.stringify({
operation: "shutdown",
timeout: 120
});
I successfully receive the json but I am unable to parse it.
Update:
I've updated the code to include the server code in its entirety.
To be perfectly clear, using the following code:
....
}).on('end', function() {
console.log("body " + body);
var json = JSON.parse(body); // trying to parse the json
handleData(json);
});
I get this:
However, this:
....
}).on('end', function() {
console.log("body " + body);
//var json = JSON.parse(body); // trying to parse the json
//handleData(json);
});
produces this
Can we see the server code, please?
Here is a working end-to-end example which is (more or less) what you are attempting, I believe.
"use strict";
const http = require('http');
/********************
Server Code
********************/
let data = {
operation: 'shutdown',
timeout: 120
};
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(JSON.stringify(data));
res.end();
});
server.listen(8888);
/********************
Client Code
********************/
let options = {
hostname: 'localhost',
port: 8888,
path: '/',
method: 'POST',
headers: {
'Accept': 'application/json'
}
};
let req = http.request(options, res => {
let buffer = '';
res.on('data', chunk => {
buffer += chunk;
});
res.on('end', () => {
let obj = JSON.parse(buffer);
console.log(obj);
// do whatever else with obj
});
});
req.on('error', err => {
console.error('Error with request:', err);
});
req.end(); // send the request.
It turns out that as this is a cross-origin(cors) request, it was trying to parse the data sent in the preflighted request.
I simply had to add an if to catch this
....
}).on('end', function() {
if (request.method !== 'OPTIONS') {
var data = JSON.parse(body);
handleData(data);
}
});
Further reading if you're interested: HTTP access control (CORS)
Put the identifiers in quotes.
{
"operation": "shutdown",
"timeout": 120
}
http://jsonlint.com/ Is a helpful resource.

node.js http.request for json, undefined in front of the json

I'M trying to get data from embed.ly via node.js.
Everything looks ok but it puts an "undefined" in front of the data:
Maybe it has something to do with setEncoding('utf8) ?
The results looks like this:
undefined[{ validjson }]
The function:
function loadDataFromEmbedLy( params, queue ){
try {
var body;
var options = {
host: 'api.embed.ly',
port: 80,
path: '/1/oembed?wmode=opaque&key=key&urls='+params,
method: 'GET',
headers: {'user-agent': ''}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('end', function() {
if( typeof body != 'undefined' ){
console.log( body );
}
});
res.on('data', function ( chunk ) {
if( typeof chunk != 'undefined' ){
body += chunk;
}
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
} catch(e) { console.log("error " + e); }
}
It's because body is initially undefined. When you append to it using +=, it will append it to the string "undefined". I hope that makes sense.
Solution: declare body as the empty string: var body = "";
Second: I really recommend checking out Mikeal Rogers' request.
Edit: request is a little easier than the basic http api. Your example:
function loadDataFromEmbedLy (params) {
var options = {
url: 'http://api.embed.ly/1/oembed',
qs: {
wmode: 'opaque',
urls: params
},
json: true
};
request(options, function (err, res, body) {
console.log(body);
});
}