How to parse body params on AWS lambda? - node.js

On my AWS lambda function i have access to an event json which holds a parameter called: body. the issue is this is a raw body string (not parsed into individual parameters).
{
input: {
body: "------WebKitFormBoundarys3wLu6HlaCBrIExe\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n------WebKitFormBoundarys3wLu6HlaCBrIExe\r\nContent-Disposition: form-data; name=\"media[]\"\r\n\r\nhthtth\r\n------WebKitFormBoundarys3wLu6HlaCBrIExe\r\nContent-Disposition: form-data; name=\"media[]\"\r\n\r\nlololol\r\n------WebKitFormBoundarys3wLu6HlaCBrIExe--\r\n"
}
}
I'd like to take that and turn into:
{
foo: 'bar',
media: [
"grgkoerpkge",
"twepgbopcib"
]
}
I'd prefer not to use some bloated express server just to parse a body string.
P.S. I've tried to use body-parser but it seems like it only works with express as a middleware

const {URLSearchParams} = require('url')
const sp = new URLSearchParams(event.body)

Encountered similar issue recently, as content-type in request was plain text format, I used querystring, built in module in node js to parse body string,
more about querystring
const querystring = require('querystring');
& in lambda handler,
var jsonData = querystring.parse(event.body);

Send it to your lambda as JSON.
Then, in your lambda (if you use lambda-proxy integration), parse it by using JSON.parse(event.body).

You'r passing the params by form or with the "Content-Type" in the header "application/x-www-form-urlencoded".
You shoukd pass it with "application/json"

Related

Access individual fields from request body inside cloud function

I'm sending a post request to a cloud function which contains the following body:
{message: "this is the message"}
If I try to print the entire body of the request, it shows it, but if I try to get the message field, I get undefined in the console.
Here's my function:
exports.myCloudFunction = functions.https.onRequest((req: any, res: any) => {
console.log(req.body)\\prints the body of the request fine
console.log(req.body.message)\\prints "undefined"
cors(req, res, () => {
const pl = req.body.message;
console.log(pl);\\prints "undefined"
});
return res.send("all done")
});
You don't need a body parser for Cloud Functions as described in the other answer here. Cloud Functions will automatically parse JSON and put the parsed JSON object in the body attribute. If you want this to happen automatically, you should set the content type of the request to "application/json" as described in the linked documentation. Then you can use req.body as you'd expect.
I personally haven't worked with firebase before, but from your code and the fact that req.body prints the body, it seems that you probably need to parse the request-body as json in order to be able to access the message property:
const body = JSON.parse(req.body);
console.log(body.message);
It could also be the case that you need to setup a bodyparser for json content. In a normal express-app you can do this using (note that you don't need the manual parsing from above anymore using bodyparser):
const bodyParser = require('body-parser');
app.use(bodyParser.json();
EDIT:
see Doug's answer for the correct way to do this, i.e. to fix your request and set the content-type to application/json in order for Cloud Functions to automatically parse and populate req.body with the request body.
You need to just convert the request body into a JSON object in cloud function.
const body = JSON.parse(req.body);
// message
console.log(body.message)

NodeJS get value from formData x-www-form-urlencoded

I use HttpClient in Angular to send formdata to Nodejs.
resetPasswordRequest(email){
this.httpOptions={
headers: new HttpHeaders({
'Content-Type':'application/x-www-form-urlencoded'
})
}
const formData = new FormData();
formData.append('email',email);
return this.http.post("http://localhost:3001/forgotPassword",formData,this.httpOptions);
}
Later in NodeJS,I have app.use(bodyParser.urlencoded({extended:true}).
I am able to get req.body but in a different format as below:
{ '-----------------------------24875245787704\r\nContent-Disposition: form-data; name':
'"email"\r\n\r\abcd#gmail.com\r\n-----------------------------24875245787704--\r\n' }
I am not sure what has been missed. Could you please clarify and help get value of email? I get req.body.email as undefined.
From MDN FormData:
It uses the same format a form would use if the encoding type were set to "multipart/form-data"
which explains why you're getting data in that format.
You could use angular's HttpParams instead:
const formData = new HttpParams();
formData.set('email', email)
return this.http.post("http://localhost:3001/forgotPassword", formData.toString(), this.httpOptions);
toString gives you urlencoded format. From docs:
Serialize the body to an encoded string, where key-value pairs (separated by =) are separated by &s
you need to parse formData in nodejs. see this question or find similar. also are you sure you need to use formData? you can just send object in body

Node-Red POST multipart/form-data (http request)

I would like to POST two data in multipart / form-data format using Node-RED.
(One for text data, one for voice data)
I set the function node and http request node as follows, but it does not seem to be POST.
I think that it is necessary to create a multi-part body and assign it to msg.body, but I do not know how to create a multi-part body of the voice data.
I do not know how to solve it, so someone would like to tell me.
function node
var request = global.get('requestModule');
var fs = global.get('fsModule');
msg.body = {};
msg.body = {
'apikey' : "**********",
'wav' : fs.createReadStream('/tmp/testtest.wav')
};
msg.headers = {};
msg.headers['Content-type'] = 'multipart/form-data';
return msg
http request(Property)
method ⇒ POST
URL ⇒ https://xxxxyyyzzz/
SSL/TLS ⇒ No
Basic ⇒ No
Output ⇒ JSON
The http request Node-Red core node support multipart/form-data POST out of the box.
Add a function node before your http request with this Function :
msg.headers = {};
msg.headers['Content-Type'] = 'multipart/form-data';
msg.headers['Accept'] = 'application/json';
msg.payload = {
'apikey': msg.apiKey,
'wav': {
value: msg.payload.invoice.file,
options: {
filename: 'testtest.wav',
contentType: 'audio/wav', // This is optionnal
}
}
}
return msg;
The http request node use Request nodejs library under the hood, and this one use form-data library for handling multipart, so all the options supported by these works.
The source code of the relevant part of http request handling multipart.

Retrieve both string and json of body using koa js

I use koa js with bodyparser, suppose client send body like this:
{ "first": "1" , "second": "2"}
what I want is the original body as string with no changes (JSON.stringify changes the order of fields and remove spaces then I can't use it). I try to use raw-body that gives me the string of body, so I have to parse it to JSON.
is there any middleware that give me body as both json and original string?
If you want both the raw string and the JSON, get the string, keep a copy, then parse it to JSON.
var getRawBody = require('raw-body')
app.use(function* (next) {
var string = yield getRawBody(this.req, {
length: this.length,
limit: '1mb',
encoding: this.charset
})
var json = JSON.parse(string)
// do something with "string"
// do something with "json"
})
Note: You have to run getRawBody() against this.req, since that's node's raw http request object. this.request is koa-specific and won't work.

Node.js: Make a HTTP POST with params

call = "https://aaa#api.twilio.com/2010-04-01/Accounts/sasa/Calls.xml"
fields = { To : "+12321434", From : req.body.from }
request.post
url: call, body: fields (err,response,body) ->
console.log response.body
How can I pass fields to the HTTP POST request?
It works if I pass a string like "To=+12321434" but not "To=+12321434,From = req.body.from"
You need to stringify your data, look at the example:
http://nodejs.org/docs/latest/api/querystring.html#querystring.stringify

Resources