How do I properly send JSON data over Http Post on NodeJS? I have checked that the data I'm sending is definitely JSON but every time I try sending over http post, it would receive an error. I cant exactly see the error as it's returning from terminal and even if I output, it's too messy, not properly formatted
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("/var/www/node/test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('{"string": result}'); ///RESULT HERE IS A JSON
req.end();
Also tried this
// request.post(
// '',
// { form: { key: result } },
// function (error, response, body) {
// if (!error && response.statusCode == 200) {
// console.log(body);
// }
// }
// );
// console.log(result);
result is not being interpolated.
this seems to work correctly..
http = require('http');
fs = require('fs');
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
// req.write('{"string": result}'); ///RESULT HERE IS A JSON
result = '{ "hello": "json" }';
req.write('{"string": '+result+'}');
req.end();
result:
$ node 29712051.js
Status: 201
Headers: {"server":"Cowboy","date":"Sat, 18 Apr 2015 04:23:52 GMT","connection":"keep-alive","x-powered-by":"Express","content-type":"text/plain","content-length":"7","set-cookie":["connect.sid=0eGSTYI2RWf5ZTkpDZ0IumOD.OrcIJ53vFcOiQSdEbWz0ETQ9n50JBnXyZRjrSyFIdwE; path=/; expires=Sat, 18 Apr 2015 08:23:53 GMT; httpOnly"],"x-response-time":"6ms","via":"1.1 vegur"}
Body: Created
The file was saved!
$ cat test.txt
Created
actually, u can use JSON.stringify(result) to instead '{"string": '+result+'}':
http = require('http');
fs = require('fs');
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
// req.write('{"string": result}'); ///RESULT HERE IS A JSON
//
result = JSON.stringify({ hello: "json" });
req.write('{"string": '+result+'}');
//
req.end();
Related
I'm trying to access the app.get('/playlists') but it keeps coming up a 404 status code error and the browser is displaying cannot GET /playlists
I'm unsure what I'm doing tthat is isn't accessible here's the code:
var express = require('express'); // Express web server framework
var stateKey = 'spotify_auth_state';
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cors())
.use(cookieParser());
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
var code = req.query.code || null;
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
if (state === null || state !== storedState) {
res.redirect('/#' +
querystring.stringify({
error: 'state_mismatch'
}));
} else {
res.clearCookie(stateKey);
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: redirect_uri,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' +
client_secret).toString('base64'))
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token,
refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
// we can also pass the token to the browser to make requests from there
res.redirect('/#' +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token
}));
} else {
res.redirect('/#' +
querystring.stringify({
error: 'invalid_token'
}));
}
});
}
});
app.get('/refresh_token', function(req, res) {
// requesting access token from refresh token
var refresh_token = req.query.refresh_token;
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.send({
'access_token': access_token
});
}
});
app.get('/playlists', (req, res) => {
console.log(request.url);
response.send('Hello, /');
});
});
console.log('Listening on 8888');
app.listen(8888);
I can't figure out why the route won't work
Your /playlists endpoint is declared inside of the /refresh_token endpoint. Moving it outside of that should work.
I try to learn nodeJS and AngularJS using Clash of clan API available here https://developer.clashofclans.com/#/
My JSON api's return is truncated and i don't know how get the full response.
there is my app.js wrinting with node and express :
var express = require('express')
, https = require('https')
, bodyParser = require('body-parser')
, request = require('request')
, app = express()
, http_port = 3000;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
var options = {
host: 'api.clashofclans.com',
port: 443,
path: '/v1/clans/' + encodeURIComponent("#PP8JC9RQ"),
headers : {
accept : "application/json",
authorization : "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6ImQ4Njg1OGFhLWQzZTUtNDNiOC05MTM1LTBjNzI1ZjI4OGFiMiIsImlhdCI6MTQ1NjMwMTE5MSwic3ViIjoiZGV2ZWxvcGVyLzk1YWM0YjdmLTY5NTQtMDE3MC01ZjAyLTcxNjY1ZDMzYjUwNyIsInNjb3BlcyI6WyJjbGFzaCJdLCJsaW1pdHMiOlt7InRpZXIiOiJkZXZlbG9wZXIvc2lsdmVyIiwidHlwZSI6InRocm90dGxpbmcifSx7ImNpZHJzIjpbIjg3LjIzMS4yMTMuMTU0Il0sInR5cGUiOiJjbGllbnQifV19.SYqeSAF-0_bM1eS2-hnovvj5j-I0SQpdr_kySIiBKw9OkrNuBzZAOAOkiH3fzdKSkcHaJfXzWdXr8JozFfAmJA"
},
method: 'GET'
};
// Route par défaut
app.get("/members", function(req, res) {
console.log("-------------------------------------\n\nroot path !! Let's get clan infos from coc api\n\n-------------------------------------");
var req = https.request(options, function(response){
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
// in console JSON is full but in my html JSON is truncated..
res.send(chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
app.listen(http_port,function(){
console.log("Listening on " + http_port);
});
If someone can teach to a nook :)
Your code is sending the first chunk of the response immediately back to the user. You need to wait until the entire HTTP response is done. Try something like this:
app.get("/members", function(req, res) {
var req = https.request(options, function(response){
var httpResult = '';
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
httpResult += chunk;
});
response.on('end', function() {
res.send(httpResult);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
See how I append to a var each time the data event is called and when it is done - then I send the output.
Because you use send method instead write (send non-streaming). Try this:
app.get("/members", function(req, res) {
https.request(options, function(response){
response.on('data', function (chunk) {
res.write(chunk);
});
response.on('end', function () {
res.end();
});
}).end();
});
response is a stream, you can simply pipe it to res:
app.get("/members", function(req, res) {
https.request(options, function(response) {
response.pipe(res);
});
});
I'm looking into the most efficient way to get multiple JSON files from different API endpoints using node.
Basically i'd like to store each JSON object in a variable, and send them all to Jade template files for parsing.
I've got it setup working for getting one single JSON file (jsonFile1) by doing the following:
httpOptions = {
host: 'api.test123.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
}
var jsonFile1;
http.get(httpOptions, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
jsonFile1= JSON.parse(body)
console.log("Got response: " + jsonFile1);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
app.set('views', __dirname);
app.get('/', function(req, res) {
res.render('home', {
data: jsonFile1
});
});
But i don't really want to have to repeat all of this to get multiple json endpoints and send them to home jade template.
Any ideas to do this efficiently?
Based on your code, this is a quick example using the excellent async library.
var async = require('async'),
// Array of apis
httpOptions = [
{
host: 'api.test123.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
},
host: 'api.test234.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
}
];
// Put the logic for fetching data in its own function
function getFile(options, done) {
http.get(options, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
done(null, JSON.parse(body));
console.log("Got response: " + jsonFile1);
});
}).on('error', function(e) {
done(e);
console.log("Got error: " + e.message);
});
}
app.get('/', function(req, res) {
// Map the options through the getFile function, resulting in an array of each response
async.map(httpOptions, getFile, function (err, jsonFiles) {
// You should probably check for any errors here
res.render('home', {
data: jsonFiles
});
});
});
So I have a Node.js script and a Javascript file communicating with each other, and everything works except the Node.js is supposed to return data for an .mp3 file.
The data is binary, it looks like gibberish, how would I take that data it returns and allow the user to download it on a webpage using Javascript?
It gets data using http.responseText by the way.
Node.js Code
//initilization
var querystring = require('querystring');
var http = require('http');
var url = require('url');
var fileSystem = require('fs');
var path = require('path');
var util = require('util');
//convert function
function convert(voiceToUse, textToConvert, response)
{
console.log("Sending Convert Request...");
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'convert',
voice: voiceToUse,
text: textToConvert
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.setEncoding('utf8');
res.on('data', function (chunk)
{
console.log("Body: " + chunk);
var fileId = chunk.substr(chunk.indexOf("fileid") + 7);
console.log("Converting File...");
download(fileId.substr(0, fileId.search("&")), response);
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
//download function
function download(id, response)
{
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'download',
fileid: id
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.on('data', function (chunk)
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1)
{
console.log("Downloading Chunk...");
/*var fs = require('fs'),
str = 'string to append to file';
fs.open('test.mp3', 'a', 666, function (e, id)
{
fs.write(id, chunk, 0, chunk.length, 0, function ()
{
fs.close(id, function ()
{
});
});
});*/
response.write(chunk, "binary");
}
else
{
download(id, response);
}
});
res.on('end', function ()
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1){
response.end();
}
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
http = require('http');
fs = require('fs');
server = http.createServer( function(req, res) {
console.dir(req.param);
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
req.on('end', function () {
console.log("Body: " + body);
if(body){
convert('engfemale1', body, res);
res.writeHead(200, {
'Content-Type': 'audio/mp3',
'Content-Disposition': 'attachment; filename="tts.mp3"'
});
}
});
}
});
port = 8080;
server.listen(port);
console.log('Listening at port ' + port);
Javascript code
console.log('begin');
var http = new XMLHttpRequest();
var params = "text=" + bodyText;
http.open("POST", "http://supersecretserver:8080", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//http.setRequestHeader("Content-length", params.length);
//http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {
console.log('onreadystatechange');
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);//response text is binary mp3 data
}
else {
console.log('readyState=' + http.readyState + ', status: ' + http.status);
}
}
console.log('sending...')
http.send(params);
console.log('end');
You could try using data URLs:
mp3 download
Not the best browser support though.
It is also possible to use data URLs directly in audio tags.
A better solution would be to save the mp3 on your server somewhere and return a link to it for a mp3 player to use.
I am using the sample code from nodejs.org and trying to send the response to the browser .
var http = require("http");
var port = 8001;
http.createServer().listen(port);
var options = {
host: "xxx",
port: 5984,
//path: "/_all_dbs",
path: "xxxxx",
method: "GET"
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
var buffer = "";
buffer += chunk;
var parsedData = JSON.parse(buffer);
console.log(parsedData);
console.log("Name of the contact "+parsedData.name);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write("hello");
req.end();
But req.write("hello") just does not output the string to the browser ?
Is this not the right way ? can someone also tell me how to output the response to the html in views folder so that i can populate the response to the static html .
Try this:
var http = require('http');
var options = {
host: "127.0.0.1",
port: 5984,
path: "/_all_dbs",
method: "GET"
};
http.createServer(function(req,res){
var rq = http.request(options, function(rs) {
rs.on('data', function (chunk) {
res.write(chunk);
});
rs.on('end', function () {
res.end();
});
});
rq.end();
}).listen(8001);
Edit:
This node script saves the output to a file:
var http = require('http');
var fs=require('fs');
var options = {
host: "127.0.0.1",
port: 5984,
path: "/_all_dbs",
method: "GET"
};
var buffer="";
var rq = http.request(options, function(rs) {
rs.on('data', function (chunk) {
buffer+=chunk;
});
rs.on('end', function () {
fs.writeFile('/path/to/viewsfolder/your.html',buffer,function(err){
if (err) throw err;
console.log('It\'s saved!');
});
});
});
rq.end();