My URL:
http://abcde.com/result.aspx?q=(some%20name%20here%20):Done&p=1&pos=0&qType=2
Its working in postman and also in curl command. If i try this in nodejs code
var http = require("http");
var options = {
"method": "GET",
"hostname": "abcde.com",
"port": null,
"path": "/result.aspx?q=(some%2520name%2520here%2520)%3ADone&p=1&pos=0&qType=2",
"headers": {
"cache-control": "no-cache",
"postman-token": "8e755cba-5d19-446f-269e-e880bd8cd7e1"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
Its not working. I think, problem is some special characters in query params. can anyone know how to fix this issue.
Related
I'm trying to fetch API data from antares (IoT Platform) using native javascript, here's the code
var url = 'https://platform.antares.id:8443/~/antares-cse/antares-id/SuhuPagarsih/Temperature/la';
var opt = {
method: 'GET',
mode: 'no-cors',
headers: {
'X-M2M-Origin': 'bdc2996719c6ac07:8cbb60e9c5997e74',
'Content-Type': 'application/json;ty=4',
'Accept':'application/json',
},
}
fetch(url, opt)
.then(function(data) {
console.log(data)
})
.catch(function(err) {
console.error(err)
})
Here's the result
as you can see, it's failed. Most of the time I see the error reason is forbidden. But when I try using node js and snippet code from postman. I get a good result (200 OK) Here's the code if you need to compare (I guess it's all the same)
var http = require("https");
var options = {
"method": "GET",
"hostname": "platform.antares.id",
"port": "8443",
"path": "/~/antares-cse/antares-id/SuhuPagarsih/Temperature/la",
"headers": {
"x-m2m-origin": "bdc2996719c6ac07:8cbb60e9c5997e74",
"content-type": "application/json;ty=3",
"cache-control": "no-cache",
"postman-token": "ff6cbe83-97ac-6ed5-aaec-e2bafaf44002"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
And here's the result
My questions is, what seems to be the problem? what's the difference between making API request from native javascript and node js? and how can I resolve this problem?
Or maybe is there anyway around this issues? My goal is only to show the data from API to HTML/Web Page
Thank you!
I am currently switching from aws lambda to azure functions and try to convert my lambda function (js) to azure function (js). One of the things I need to do in my function is to send a HTTPS Post Request to a URL to get some data. That worked perfectly fine in aws lambda. However, it seems like azure functions is either not supporting this or I am doing something wrong as it never sends the request and just ends the whole function.
This is my code:
var https = require('https');
var http = require('http');
module.exports = async function (context, req) {
var http_options = {
hostname: 'somehostname',
port: 443,
path: 'somepath',
method: 'POST',
headers: {
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"https://someURL"'
}
};
var body = '';
context.log('before request');
var req = await https.request(http_options, function (res) {
res.setEncoding('utf8');
body = '';
context.log('inside request');
res.on('data', (chunk) => {
body = body + chunk;
});
context.log('in req 2');
res.on('end', () => {
var options = {
compact: false,
ignoreComment: false,
spaces: 1
};
var result = JSON.parse(body);
})
})
};
The function always prints the "before request" part, and the just terminates.
I also tried a simple http call as described in this SO question. However, same result, the function just ends.
I don't think that https.request() is an async method (doesn't return a promise-like type). What if you try removing your await keyword there?
var https = require('https');
var http = require('http');
module.exports = async function (context, req) {
var http_options = {
hostname: 'somehostname',
port: 443,
path: 'somepath',
method: 'POST',
headers: {
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"https://someURL"'
}
};
var body = '';
context.log('before request');
https.request(http_options, function (res) {
res.setEncoding('utf8');
body = '';
context.log('inside request');
res.on('data', (chunk) => {
body = body + chunk;
});
context.log('in req 2');
res.on('end', () => {
var options = {
compact: false,
ignoreComment: false,
spaces: 1
};
var result = JSON.parse(body);
});
});
};
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a function that does POST request to get access tokens from an API. The function works insofar as printing the token to the console but I couldn't find a way to parse and save the access-token to a variable for using in other methods.
I've searched a lot about these on Stack Overflow, and one thing I came across was the notion of callbacks, async/await... However there is no concrete answers that show me how to RETURN the value after the request is made.
I'm getting undefined values, probably because my function is executing too fast before the request ends but nonetheless I would like to know a specific code implementation (using another callback function or something different) that allows me to get the value accessible outside these asynchronous functions.
My code is below along with a screenshot. Keep in mind this is a Lambda code for an Alexa skill
function ParseToken(obj) {
var string = obj + "";
return string;
}
function httpRetrieveToken() {
var http = require("https");
var options = {
"method": "POST",
"host": "hostName",
"path": "pathVal",
"headers": {
"content-type": "contentType",
"Authorization": "Bearer token",
"cache-control": "no-cache",
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write("stuff here");
req.end();
}
Parsing token
Once you have the text representing your token object you can use JSON.parse to convert it to an object:
var json = '{"token":"ABCDEFG123456789", "expires":36000}';
obj = JSON.parse(json);
console.log(obj.token);
// expected output: ABCDEFG123456789
Using Callback
You can send a callback function as parameter to the httpRetrieveToken function like:
var http = require("https");
function httpRetrieveToken(cb) {
var options = {
"method": "POST",
"host": "hostName",
"path": "pathVal",
"headers": {
"content-type": "contentType",
"Authorization": "Bearer token",
"cache-control": "no-cache",
}
};
var req = http.request(options, function (res) {
var _cb = cb;
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
var token = JSON.parse(body.toString());
_cb(token); // Callback function
});
});
req.write("stuff here");
req.end();
}
Then you can use function like:
httpRetrieveToken(function(token) {
// Do something with the token
});
The reason to use a callback function is to execute it once the asynchronous process has been finished, then enclose in that callback the processes to follow with the required data.
Using Promise
Using promise object, you provide a function who executes either resolve when your process was successful or reject when you had an error. Then you set a function to be executed on sucess with then method, where you can use the token retrived by your http request.
var http = require("https");
function httpRetrieveToken() {
var options = {
"method": "POST",
"host": "hostName",
"path": "pathVal",
"headers": {
"content-type": "contentType",
"Authorization": "Bearer token",
"cache-control": "no-cache",
}
};
return new Promise(function(resolve, reject) {
let req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
var token = JSON.parse(body.toString());
resolve(null, token); // Callback function
});
});
req.on("error", function(err) {
reject(err);
});
});
}
httpRetrieveToken().then((err, token) => {
if(err) console.log(err);
// Do something with token
});
i am trying to connect to my neo4j db in lambda function. but keeps getting the "Unable to deserialize request: Unexpected end-of-input: expected close marker for ARRAY" error. but all seems fine when sending requesting in webapp using same parameters. Here's my request body:
var request = {"statements":
[
{
"statement": "MATCH (p:COMPANY {id: " + event.ID + "})<-[:MADE_BY]-(FRANCHISE) RETURN FRANCHISE"
}
]
};
var options = {
host: hostname,
path: pathname,
method: 'POST',
port: portnumber,
headers: {
"Authorization": authInfo,
"Content-Type": "application/json",
'Content-Length': Buffer.byteLength(request)
},
};
console.log(JSON.stringify(request));
var req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(JSON.stringify(request));
req.end();
also tried print out the JSON.stringify(request) result but it seems ok to me.
When you call Buffer.byteLength(request), you are passing the request object itself instead of the JSON-stringified form of that object. This causes the Content-Length header value to be too small.
Try this instead:
var request = {"statements": [ {
"statement": "MATCH (p:COMPANY {id: {event_id} })<-[:MADE_BY]-(FRANCHISE) RETURN FRANCHISE",
"parameters": {
"event_id": event.ID
}
} ]
};
var request_str = JSON.stringify(request);
var options = {
host: hostname,
path: pathname,
method: 'POST',
port: portnumber,
headers: {
"Authorization": authInfo,
"Content-Type": "application/json",
'Content-Length': Buffer.byteLength(request_str)
},
};
console.log(request_str);
var req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(request_str);
req.end();
Notice also that this code passes event.ID as a parameter, which is more efficient if this code will be called repeatedly.
I have nodeApp. It does stuff.
At a particular time I need to communicate with an API that out there in the wild. Using the API in rest tool like Postman is straight forward:
Postman
Url:
https://epicurl
Headers:
Content-Type : application/json
Accept : application/json
x-key : secret
Body:
{
"some":"kickass"
"data":"here"
}
Sending the above in Postman I get a nice quick response! Yay for rest tools.
So their API works, now I need to make that same response in my Node.js application.
This is where things get odd...
Request Module: FAILS
var request = require('request')
...lots_of_other_stuff...
var options = {
uri: 'https://epicURL',
method: 'POST',
json: true,
headers : {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"secretbro"
},
body : JSON.stringify(bodyModel)
};
request(options, function(error, response, body) {
if (!error) {
console.log('Body is:');
console.log(body);
} else {
console.log('Error is:');
logger.info(error);
}
cb(body); //Callback sends request back...
});
The above fails.. It throws the good'ol ECONNRESET error that we all love! Why? Who knows?
https.request() - WORKS!
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
var headers = {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"nicetrybro"
}
var options = {
host: 'www.l33turls.com',
port:443,
path: "/sweetpathsofjebus",
method: 'POST',
headers: headers
};
var req = https.request(options, function(res) {
res.setEncoding('utf-8');
var responseString = '';
res.on('data', function(data) {
responseString += data;
});
res.on('end', function() {
var resultObject = responseString;
//Call the callback function to get this response object back to the router.
cb(resultObject);
});
});
req.on('error', function(e) {
console.log(e);
});
req.write(bodyString);
req.end();
But then I notice...
If i leave this line of code in place when using the Request Module it then works...
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
Is this documented somewhere and I am missing it? Anyone explain this to me?