Getting request body from response object - node.js

I'm trying to retrieve the body of a request via the response object.
var request = require('request');
request({
...
body: {
foo: 'bar'
}
}, function(err, res, body) {
var reqBody = res.request.body;
});
But the request body is now a Buffer. How can I turn this back into a JavaScript object?
Note: I can't store the request body in a variable with larger scope before making the http request.

Figured it out, way simpler than I thought.
var reqBody = res.request.body.toString();
reqBody = JSON.parse(reqBody);
First convert it to JSON, then convert the JSON to a JavaScript object.

Related

Making a POST request using puppeteer with JSON payload

I'm trying to make a POST request using puppeteer and send a JSON object in the request, however, I'm getting a timeout... if I'm trying to send a normal encoded form data that at least a get a reply from the server of invalid request...
here is the relevant part of the code
await page.setRequestInterception(true);
const request = {"mac": macAddress, "cmd": "block"};
page.on('request', interceptedRequest => {
var data = {
'method': 'POST',
'postData': request
};
interceptedRequest.continue(data);
});
const response = await page.goto(configuration.commandUrl);
let responseBody = await response.text();
I'm using the same code to make a GET request (without payload) and its working
postData needs to be encoded as form data (in the format key1=value1&key2=value2).
You can create the string on your own or use the build-in module querystring:
const querystring = require('querystring');
// ...
var data = {
'method': 'POST',
'postData': querystring.stringify(request)
};
In case you need to submit JSON data:
'postData': JSON.stringify(request)
If you are sending json, you need to add "content-type": "application/json". If you don't send it you can receive an empty response.
var data = {
method : 'POST',
postData: '{"test":"test_data"}',
headers: { ...interceptedRequest.headers(), "content-type": "application/json"}
};
interceptedRequest.continue(data);

Sending Form Data with the native node module

for my current project I have to send form-data from my lambda function to an api endpoint. The api endpoint essentially expects two images (that it compares with one another) and a key. As mentioned before, I somehow seem unable to send the correct form-data to the api endpoint. I checked out postman, and it seems to have worked alright, but something doesn't seem to work in my function. I presume it must be related the form-data string that I'm sending. Below you can find a shortened version of the function (I excluded the two image files), but somehow I'm getting an error back telling me that the api cannot read the key property:
const http = require('http');
const https = require('https');
const httpPromise = (protocol, params, postData) => {
return new Promise((resolve, reject) => {
const requestModule = protocol === 'http' ? http : https;
const req = requestModule.request(params, res => {
// grab request status
const statusCode = res.statusCode;
if(statusCode < 200 || statusCode > 299) {
throw new Error('Request Failed with Status Code:', statusCode);
}
let body = '';
// continuosly update data with incoming data
res.setEncoding('utf8');
res.on('data', data => body += data);
// once all data was received
res.on('end', () => resolve(body));
})
// write data to a post request
if(typeof(params.method) === 'string' && params.method === 'POST' && postData) {
req.write(postData)
}
// bind to the error event
req.on('error', err => reject(err));
// end the request
req.end();
})
}
const controller = async () => {
const apiKey = "00000000";
const options = {
hostname: '***"
port: 80,
path: '***'
method: 'POST',
headers: {"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"}
}
const postData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\00000000\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
let result = await httpPromise('http', options, postData)
console.log(result);
}
yeah, so somehow it just doesn't seem to recognise the key in the postData string. I have tried various different combinations but just can't seem to get this to work.
The default http and https libraries are kind of wordy and annoying.
Would recommend using the request library instead. Read more here
In which case, to make the request, you can simply write it as :
var request = require('request');
var formData = {
// Pass a simple key-value pair
my_field: 'my_value',
}
request.post({url:'http://service.com/upload', formData: formData}, (err, response, body) => {
// Handle response here
});
Alright, so for anyone who might also face the same issue, it took me a little but figured out what the issue was. I didn't set the Content-Length header, which then in turn meant that node automatically added the Transfer-Encoding Header and set its value to chunk. This broke the receiving api and resulted in the issue. Setting the Content-Length header to the correct length and setting the Transfer-Encoding Header to an empty string solved my issue here (but I think one could also simply omit the transfer-encoding header once you defined the Content-Length Header).

How to get response header in node.js

I'm working on a nodejs project, I use request module to submit restful request and get response. (here is the module link: https://github.com/request/request)
Following the instruction, I should be able to get the response header by calling response.headers[''], however, seems it doesn't work, when I try to call var contentType = response.headers['Content-Type'], the contentType is undefined. (When I use postman, I could get Content-Type from the response). Anyone knows what's wrong?
This is the instruction from the site:
var request = require('request')
request(
{ method: 'GET'
, uri: 'http://www.google.com'
, gzip: true
}
, function (error, response, body) {
// body is the decompressed response body
console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
console.log('the decoded data is: ' + body)
}
In node, the headers are accessed by using lowercased names, so using response.headers['content-encoding'] is correct.
Your code snippet currently works for me and displays 'server encoded the data as: gzip.'

Get the response "ContentType" in a nodejs http request

I want to donwload a file via http and check the "ContentType" response header. My Download looks like this:
var fileUrl = "<url>";
var request = https.get(fileUrl, function (res) {
res.on('data', function (data) {
//...
});
res.on('error', function (error) {
//...;
});
I get the data, but is there any way to acces the content type resonse header?
The res variable is an instance of http.IncomingMessage, which has a headers property that contains the headers:
var request = https.get(fileUrl, function (res) {
var contentType = res.headers['content-type'];
...
});
If you want to get only mime-type, be aware that Content-Type header can include other information such as charset or boundary.
Use parser such as content-type-parser instead of reading header directly.
const contentTypeParser = require("content-type-parser");
const contentType = contentTypeParser(req.headers['content-type']);
const mimeType = contentType.type+'/'+contentType.subtype;

request node.js module can't send a simple POST

I send it like so :
var url = "http://localhost:9001/v1/sanger/auth/facebook/callback",
options = {body: JSON.stringify(params), 'Content-type': 'application/json'};
request.post(url, options, function (error, response, body) {
... callbacks ...
});
I am not getting the params in the route (tried body, params and query)
When I use postman (http://cl.ly/image/473e2m173M2v) I get it in the req.body
A better way to do this (I'm assuming you've initialized your params variable somewhere else):
request = require('request');
var options = {
url: "http://localhost:9001/v1/sanger/auth/facebook/callback",
method: 'POST',
body: params,
json: true
};
request(options, function (error, response, body) {
... callbacks ...
});
You're not able to get the body because when you call JSON.stringify(params), you're converting params to a string and you don't have a json object anymore. If you send the information as plain/text but tell the request that you want json, your express app cannot verify the content-type, as could check with:
request.get('Content-Type'); // returns undefined
Since you want a json object, you shouldn't do this. Just pass the json object, like in the example above.
Then, in your route code, you can do both req.body or req.param('a_param') (for a especific key of your json) to get those values.

Resources