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:
- The landing page stringifies the object with
JSON.stringify
- Convert in base64 of that with
btoa
- Encode for URL with
encodeURIComponent
- Redirect to the other website with result in the query of the URL
- The other website decode
decodeURIComponent
- Decode again with
atob
- Extract the object with
JSON.parse
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:
- The landing page stringifies the object with
JSON.stringify
- Encode the string with
encodeURIComponent
- Convert in base64 of that with
btoa
- Encode for URL with
encodeURIComponent
(not entirely necessary as base64 is already URI compatible but good to have anyway) - Redirect to the other website with result in the query of the URL
- The other website decode
decodeURIComponent
- Decode again with
atob
- Decode again with
decodeURIComponent
- Finally, extract the object with
JSON.parse
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.
Top comments (2)
Try these, they seem to work with all the examples from Stack Overflow
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
orbtoa
solution (if you don't want some complex webpack that can simulate a buffer or any external buffer-ish libraries).