Encoding mess with Javascript

antho1404 profile image Anthony ・2 min read

Today, I launched a new feature on a product I'm working on, letting you deploy a cloud function quickly. (Not the subject but if you're interested it's here).
Like any launch, there are always some last minutes issues, and I discovered something interesting.

I was trying to transfer data from one page (the landing page) to another one (the console). These data contain the content of the function you want to deploy so, a lot of characters like ", {, (... that's where it gets funny.

The encoding was done with the following flow:

So far so good. We should have:

const data = {...}
const encoded = encodeURIComponent(btoa(JSON.parse(data)))
// other website
const decoded = JSON.parse(atob(decodeURIComponent(encoded)))
data === decoded

But no...
Some characters like > (used to define an arrow function) are messing up with the encoding, and it is impossible to recover the data (more details here).

So if you already had this issue here is a sweet fix:
You can add another encode/decodeURIComponent before the atob/btoa call.

So now your flow would be:

So that would be equivalent to:

const data = {...}
const encoded = encodeURIComponent(btoa(encodeURIComponent(JSON.parse(data))))
// other website
const decoded = JSON.parse(decodeURIComponent(atob(decodeURIComponent(encoded))))
data === decoded

Now the data can be decoded with the right content 🎉

I struggled a bit today about that, so I thought I would share it. If you have any ways to do that properly, I would love to hear your feedback, and if you want to try to break it again, you can do it here https://liteflow.com/functions.


Editor guide
jpantunes profile image
JP Antunes

Try these, they seem to work with all the examples from Stack Overflow

const asciiToBase64 = ascii => Buffer.from(ascii).toString('base64');
const base64ToAscii = b64 => Buffer.from(b64, 'base64').toString();
antho1404 profile image
Anthony Author

Yes, that works well but only in node environment. In javascript in the browser, Buffer is not accessible and thus you need to go with the atob or btoa solution (if you don't want some complex webpack that can simulate a buffer or any external buffer-ish libraries).