NodeJS get value from formData x-www-form-urlencoded - node.js

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

Related

React sending empty object instead of formData to API

I did the following request with JS and it worked. Now trying to adapt in for react and getting an empty object being posted. Below just bits of code, but basically I am generating pdf and aiming to send it to backend:
const doc = new jsPDF();
const blob = doc.output('blob');
const email = formData.emailRequired;
const formDataToSend = new FormData();
formDataToSend.append('email', email);
formDataToSend.append('file', blob);
console.log(formDataToSend)
fetch('http://localhost:8080/api/contract',
{
method: 'POST',
data: formDataToSend,
processData: false,
contentType: false,
});
Unfortunatelly on submit I get FormData {} - so it's an empty object. Why?
FormData is not an empty object, it is displayed like this in the console.
If you want to display all entries, then use this approach
console.log([...formDataToSend.entries()])
Related question How to inspect FormData?

How to make both req.files and req.body available in nodejs when the api is sent with axios

I'm using Axios npm package in my Node.js application which is a built-in microservices architecture. API-gateway is using Axios to call other services.
According to axios documentation, for POST method, request format is like: axios#post(url[, data[, config]]) . means only one argument data.
Can anyone tell me how I can send req.body & req.files data separately to Axios?
According to answer in Axios community to familiar question this could be achieved with the npm package form-data, which simulates WebAPI FormData on the node side.
This would allow you to send files and form fields to the API and receive it in form of multipart form data.
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
// Second argument can take Buffer or Stream (lazily read during the request) too.
// Third argument is filename if you want to simulate a file upload. Otherwise omit.
form.append('field', 'a,b,c', 'blah.csv');
axios.post('http://example.org/endpoint', form, {
headers: form.getHeaders(),
})
.then(result => {
// Handle result…
console.log(result.data);
});
Bundle your data up as an object, and pass that object through to the axios request as a single payload.
On the other side of the API, you can access the object, and do as you wish.
var payload = { property1: 'values', property2: 'values2' }
now you pass payload around

Getting a bad request 400 when trying to upload zipped wkt file to here-maps rest api

We have a problem with the fleet.ls.hereapi.com when uploading a new layer for geofencing.
const myId = 'MYLAYER'; // just a id to check
zip.file('data.wkt', `NAME\tWKT\n${myId}\t${wkt}`);
const content = await zip.generateAsync({ type: 'nodebuffer' });
const formData = new FormData();
formData.append('zipfile', content);
await axios.post(config.HERE_MAPS_UPLOAD_ENDPOINT, formData, {
headers: {
'content-type': 'multipart/form-data',
},
params: {
apiKey: config.HERE_MAPS_REST_API_KEY,
layer_id: myId,
},
});
We get a bad request without a message and do not know what the problem is. The same implementation works in the Frontend (with 'blob' as zip type). Is there a parameter to get a better error message from the api?
We got the instructions how to implement it from this tutorial: https://www.youtube.com/watch?v=Ayw9GcS1V-8 and as I mentioned it works fine in the frontend. Also it works if I write a file in node and upload it via curl. Thank you for any help in advance!
Edit: I'm getting the following issue from the API: 'Multipart should contain exactly one part but contains 0'
I fixed it!
The problem was that the api needed a filename for the form data. This filename can be provided as third parameter as described here.
So I basically changed formData.append('zipfile', content); to formData.append('zipfile', content, zipfile.zip); and it worked.
Hope this will help somebody in the future!

POST request to retrieve pdf in node.js

I am making a POST request to retrieve a pdf. The request works fine if I do it in postman, but I get an empty pdf if I do it through node.js using the request package. Here's my request using the request package:
let body = {
attr1: "attr1",
attr2: "attr2"
}
let opts = {
url: "some_url",
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body
}
request(requestOpts).then(pdf => {
console.log(pdf) // prints out the binary version of the pdf file
fs.writeFileSync("testing.pdf", pdf);
});
I use the exact same request parameters when I use postman but it returns the pdf w/ the correct content.
Can someone help? Or is the way I am saving my pdf incorrect?
Thanks in advance!
Solution - i had to set encoding: false in the request options.
Try
fs.writeFileSync("testing.pdf", pdf, 'binary');
The third argument here tells fs to write binary rather than trying to UTF-8 encode it.
According to the docs the third paramter should be a string that represents the encoding.
For pdf files the encoding is 'application/pdf'
So this should work for you : fs.writeFileSync("testing.pdf", pdf, 'application/psf');

How to parse body params on AWS lambda?

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"

Resources