I was intending to set a cookie, and want do to some work with that in client side JS.
While decoding the URI through decodeURIComponent() function, some undesired characters were appended before the URI and also in decoded URI. I did a quick fix by removing some of the first characters in my URI and decoding it to get JSON,
I would like to know why was j: added in URI and also how to deal with it.
Also : It looks right i.e nothing was appended in cookie when seeing decoded URI in DevTools
For setting my cookie having name as note with JS object
res.cookie('note',note,{maxAge : 1000*60*60*24});
let decoded = decodeURIComponent(document.cookie.substring(9, ));
decoded = JSON.parse(decoded);
I did this to decode my cookie
and converting JSON I got from decodeURIComponent fun to JS Object which I want to use
I tried encoding my object with encodeURIComponent but it seems it automatically get encoded.
Related
I have some legacy code (pre-React) that encodes part of a URL with encodeURIComponent before calling history.push() on the https://www.npmjs.com/package/history module in order to navigate to that URL.
history.push() inside history.js then uses decodeURI to decode the entire URL partially (decodeURI only decodes the same characters that encodeURI encodes)
this partially decoded location.pathname ends up in ReactRouter where useParams() gives me the partially decoded URL component back again.
Now I'm stuck with a partially decoded URL component which I cannot use. I need it fully decoded.
I can't use decodeURIComponent on the partially decoded string, because the original string might contain a %, in which case this % will already be decoded in the partially decoded string and this would cause decodeURIComponent to crash with a Uncaught URIError: URI malformed.
My options seem to be:
use unescape to fully decode the partially decoded string (it doesn't complain about the single %) even though its use is discouraged (why?)
manually re-encode any % (that isn't followed by a digit and a subsequent hex character) back to %25 and then run the result through decodeURIComponent
Are there any less ugly solutions that I haven't thought of yet ?
EDIT : I was asked for examples of what I meant by partially decided string
const original = 'A-Za-z0-9;,/?:#&=+$-_.!~*()#%';
const encodedURIComponent = encodeURIComponent(original); // "A-Za-z0-9%3B%2C%2F%3F%3A%40%26%3D%2B%24-_.!~*()%23%25"
console.log(decodeURIComponent(encodedURIComponent)); // "A-Za-z0-9;,/?:#&=+$-_.!~*()#%"
const partiallyUnescaped = decodeURI(encodedURIComponent); // "A-Za-z0-9%3B%2C%2F%3F%3A%40%26%3D%2B%24-_.!~*()%23%" - notice the '%25' at the end was decoded back to '%'
console.log(unescape(partiallyUnescaped)); // "A-Za-z0-9;,/?:#&=+$-_.!~*()#%"
//console.log(decodeURIComponent(partiallyUnescaped)); // error
EDIT 2: In case it can be of any help, here's a more realistic example of some of the characters our URL might contain, but because it's user generated, it could be anything really:
console.log( encodeURIComponent('abcd+%;- efgh')) ; // "abcd%2B%25%3B-%20efgh"
console.log( decodeURI(encodeURIComponent('abcd+%; -efgh'))) ; // "abcd%2B%%3B- efgh"
//console.log(decodeURIComponent(decodeURI(encodeURIComponent('abcd+%; -efgh')))); // Error: URI malformed
I am trying to encode a string in javascript and decode it in php.
I use this code to put the string in a inputbox and then send it via form PUT.
document.getElementById('signature').value= b64EncodeUnicode(ab2str(signature));
And this code to decode
$signature=base64_decode($signature);
Here there is a jsfiddle for the encoding page:
https://jsfiddle.net/okaea662/
The problem is that I always get a string 98% correct but with some different characters.
For example: (the first string is the string printed in the inputbox)
¦S÷ä½m0×C|u>£áWÅàUù»¥ïs7Dþ1Ji%ýÊ{\ö°(úýýÁñxçO9Ù¡ö}XÇIWçβÆü8ú²ðÑOA¤nì6S+̽ i¼?¼ºNËÒo·a©8»eO|PPþBE=HèÑqaX©$Ì磰©b2(Ðç.$nÈR,ä_OX¾xè¥3éÂòkå¾ N,sáW§ÝáV:ö~Å×à<4)íÇKo¡L¤<Í»äA(!xón#WÙÕGù¾g!)ùC)]Q(*}?Ìp
¦S÷ ä½m0×C|u>£áWÅàUù»¥ïs7Dþ1Ji%ýÊ{\ö°(úýýÁñxçO9Ù¡ö}XÇIWçβÆü8ú²ðÑOA¤nì6S+̽ i¼?¼ºNËÒo·a©8»eO|PPþBE=HèÑ qaX©$Ì磰©b2(Ðç.$nÈR,ä_OX¾xè¥3éÂòkå¾ N ,sá W§ÝáV:ö~Å×à<4)íÇKo¡L¤<Í»äA(!xón#WÙÕGù¾g!)ùC)]Q(*}?Ìp
Note that the 4th character is distinct and then there is one or two more somewhere.
The string corresponds to a digital signature so these characters make the signature to be invalid.
I have no idea what is happening here. Any idea? I use Chrome browser and utf-8 encoding in header and metas (Firefox seems to use a different encoding in the inputbox but I will look that problem later)
EDIT:
The encoding to base64 apparently is not the problem. The base64 encoded string is the same in the browser than in the server. If I base64-decode it in javascript I get the original string but if I decode it in PHP I get a slightly different string.
EDIT2:
I still don't know what the problem is but I have avoided it sending the data in a blob with ajax.
Try using this command to encode your string with js:
var signature = document.getElementById('signature');
var base64 = window.btoa(signature);
Now with php, you simply use: base64_decode($signature)
If that doesn't work (I haven't tested it) there may be something wrong with the btoa func. So checkout this link here:
https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
There is a function in there that should work (if the above does not)
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
b64EncodeUnicode(signature); // "4pyTIMOgIGxhIG1vZGU="
I am using the following javascript method to decode a URL.
decodeURIComponent();
When entering the encoded version in the browser it shows the expected image. Following the use of the above decode function, the new URL does not display the image.
How can I decode this properly?
The URL is:
Encoded:
"https://external.xx.fbcdn.net/safe_image.php?d=AQB9-zMODCId1OZa&w=128&h=128&url=https%3A%2F%2Fscontent.xx.fbcdn.net%2Fhprofile-xpa1%2Fv%2Ft1.0-1%2Fp200x200%2F12289537_1025015047521253_6948708859100232371_n.png%3Foh%3Dd4b09489497f8705ca75467bd6af54e9%26oe%3D578DF677&upscale=1&ext=jpg”
Decoded:
"https://external.xx.fbcdn.net/safe_image.php?d=AQB9-zMODCId1OZa&w=128&h=128&url=https://scontent.xx.fbcdn.net/hprofile-xpa1/v/t1.0-1/p200x200/12289537_1025015047521253_6948708859100232371_n.png?oh=d4b09489497f8705ca75467bd6af54e9&oe=578DF677&upscale=1&ext=jpg"
The decodeURIComponent() function isn't decoding your URI the way you expect because it's really only intended to work with strings that were previously encoded with encodeURIComponent().
Instead, you want to use decodeURI().
var url = 'https://external.xx.fbcdn.net/safe_image.php?d=AQB9-zMODCId1OZa&w=128&h=128&url=https%3A%2F%2Fscontent.xx.fbcdn.net%2Fhprofile-xpa1%2Fv%2Ft1.0-1%2Fp200x200%2F12289537_1025015047521253_6948708859100232371_n.png%3Foh%3Dd4b09489497f8705ca75467bd6af54e9%26oe%3D578DF677&upscale=1&ext=jpg';
var decoded = decodeURI(url);
document.write(decoded);
I would like to take a JSON string and encrypt/hash/encode it so that I can put it into a URL so that it would resemble something such as seen below:
var stringToEncode = JSON.stringify({foo: 'baz', bar: [1,2,3,4,5], baz: {fizzle: 'buzz'}});
'www.myrandomurl.com/someurl/123fas234asf1543rasfsafda'
I would then like to take that encrypted/hashed/encoded string, and decode it back to its original JSON string so that I can use it to bind to various elements on a single-page AngularJS application.
The contents of the JSON string are not sensitive so security or complex hashing is not required. The only condition is that It needs to be a "URL/URI 'safe'" string that is hashed for vanity purposes like seen above.
I am limited in knowledge of encrypting/encoding however I have thought about simply encoding the string to Base64 and decoding it again.
Is this the best approach? What is a better method if not?
Use encodeURIComponent() to encode it for the url
To decode use the decodeURIComponent() function
Base64 is not URL safe since it can contain non url characters like / + -. (See this question)
If you want your url to not be too similair to the original string you can first covert to base64 and then encode and reverse by decoding and covrrtibg back from base 64
// to url
encodeURIComponent(btoa(str))
// from url
atob(decodeURIComponent(uri))
In particular, when saving a JSON to the cookie is it safe to just save the raw value?
The reason I dopn't want to encode is because the json has small values and keys but a complex structure, so encoding, replacing all the ", : and {}, greatly increases the string length
if your values contain "JSON characters" (e.g. comma, quotes, [] etc) then you should probably use encodeURIComponent so these get escaped and don't break your code when reading the values back.
You can convert your JSON object to a string using the JSON.stringify() method then save it in a cookie.
Note that cookies have a 4000 character limit.
If your Json string is valid there should be no need to encode it.
e.g.
JSON.stringify({a:'foo"bar"',bar:69});
=> '{"a":"foo\"bar\"","bar":69}' valid json stings are escaped.
This is documented very well on MDN
To avoid unexpected requests to the server, you should call encodeURIComponent on any user-entered parameters that will be passed as part of a URI. For example, a user could type "Thyme &time=again" for a variable comment. Not using encodeURIComponent on this variable will give comment=Thyme%20&time=again. Note that the ampersand and the equal sign mark a new key and value pair. So instead of having a POST comment key equal to "Thyme &time=again", you have two POST keys, one equal to "Thyme " and another (time) equal to again.
If you can't be certain that your JSON will not include reserved characters such as ; then you will want to perform escaping on any strings being stored as a cookie. RFC 6265 covers special characters that are not allowed in the cookie-name or cookie-value.
If you are encoding static content you control, then this escaping may be unnecessary. If you are encoding dynamic content such as encoding user generated content, you probably need escaping.
MDN recommends using encodeURIComponent to escape any disallowed characters.
You can pull in a library such as cookie to handle this for you, but if your server is written in another language you will need to ensure it uses a library or language utilities to encodeURIComponent when setting cookies and to decodeURIComponent when reading cookies.
JSON.stringify is not sufficient as illustrated by this trivial example:
const bio = JSON.stringify({ "description": "foo; bar; baz" });
document.cookie = `bio=${stringified}`;
// Notice that the content after the first `;` is dropped.
// Attempting to JSON.parse this later will fail.
console.log(document.cookie) // bio={\"description\":\"foo;
Cookie: name=value; name2=value2
Spaces are part of the cookie separation in the HTTP Cookie header. Raw spaces in cookie values could thus confuse the server.