Hey! I was making a Netlify function that will take input of a form that contains a couple of images and some JSON data. I am sending it as a Base64 string in JSON form. In the local environment in Netlify Dev. It is working as expected, but In production, the body of the form is getting converted into base64 string and the parameter isBase64Encoded is true. And If I decoded it, then I am getting only a part of the body, it’s not full-body what I sent.
Example,
What I am sending {"name": "John}
What I am recieving {"name: "j`
Are you sure you’re encoding and returning a single string rather than several, and that there is no terminating character like ’ midstring? Sorry if that’s a dumb question but it seems good to establish that first since you didn’t share your source code.
Hey @fool
I’m facing the exact same problem as @s-r-aman, i’ll try to go a bit more in depth.
We have a json payload being sent to netlify without application/json header (we have no control over this, since its coming via webhook from our rabbitmq queue).
This is our netlify handler that we are using to test this:
export const handler = async (event, context) => {
let body = event.body;
console.log(event.body);
if (event.isBase64Encoded) {
body = Buffer.from(event.body, 'base64').toString();
console.log("isBase64Encoded");
}
console.log("Body decoded", body);
}
Thanks for the prompt reply. But I guess the problem is still there, maybe you sent the POST request to my endpoint using a content-type equal to application/json?
I’ve just tested it again, this is the simplest POST that will make the function output this wrong result
Headers:
content-type: application/octet-stream
Body
{"name": "test"}
The output was
9:51:07 PM: 2020-09-19T00:51:07.895Z 701e2c8e-3255-4fd2-994b-97b626b31da3 INFO eyJuYW1lIjogInRlc3Qi
9:51:07 PM: 2020-09-19T00:51:07.895Z 701e2c8e-3255-4fd2-994b-97b626b31da3 INFO isBase64Encoded
9:51:07 PM: 2020-09-19T00:51:07.895Z 701e2c8e-3255-4fd2-994b-97b626b31da3 INFO Body decoded {"name": "test"
Hey @gui,
Sorry for the slow reply- I was out of office, but back now and taking a look! I was indeed looking at a different function in my initial reply, so will do some testing with the one you shared.
Taking another look at this, I think what you’re running into is expected with the application/octet-stream header set in the POST request to your function. Because that header is set, we base64 encode the payload. If you were to send the POST request with a content-type header like text/plain or application/json, then we would not encode the payload.
If you don’t have control over the application/octet-stream content-type header being set for the request, then you will want to base64 encode the JSON string before POSTing to the function, so something like:
let bufferObj = Buffer.from('{"name": "test"}', "utf8");
let base64String = bufferObj.toString("base64");
Then, you can decode that within the function as you’re doing and pass it along as a string. Let us know if that helps!
Thanks for getting back to me about this. I didn’t have time to do much digging into this today, but from what i could test so far, your suggestion would result in me having to decode the body twice, am I correct?
If i encode the json before sending it, from the tests i’ve done, netlify will still encode it again, so i would have something like this
The original body:
{"name": "test"}
is sent after being converted to a encoded string
let bufferObj = Buffer.from('{"name": "test"}', "utf8");
let base64String = bufferObj.toString("base64"); // eyJuYW1lIjogInRlc3QifQ==
this is queued as eyJuYW1lIjogInRlc3QifQ== and at some point in the future sent to another function to be processed.
...
if (event.isBase64Encoded) {
let body = event.body // ZXlKdVlXMWxJam9nSW5SbGMzUWlmUT09 (encoding inception due to netlify)
let firstDecode = Buffer.from(body, 'base64').toString("utf-8"); // eyJuYW1lIjogInRlc3QifQ==
let message = JSON.parse(Buffer.from(firstDecode, 'base64').toString()) // this is {test: "name"};
}
...
Although this works, i wonder if this is the correct approach, since having to decode it twice seems a bit odd to me. I’m no expert with encoding/decoding so I apologize if this is in any way obvious.
I agree, it is weird and not ideal to double decode! The best case would be to change the content-type header on the POST to tell the function that the payload should not be base64 encoded. But since that’s not an option, this is the best workaround I know of. If you find another more concise way and are able to report back here, we would definitely love to know.