I’m writing a JavaScript function that needs to uphold three properties:
- be very small and lightweight – no external libraries
- encode a string in such a way as to be able to be passed as a GET parameter
- this string must be decoded again at its destination
Effectively, it authenticates the user by sending his username and password to a PHP page which then verifies it. This is done via GET because I haven’t yet found a way of doing a background cross-domain POST request. The trouble is that if the user has a character such as ‘#’ or similar in his password, it doesn’t get sent properly.
Currently to avoid this, I encode() the password string before sending it, which allows it to be received without problems. However, I read that PHP’s urldecode() is not a perfect analog for this, as there are corner cases which are treated differently (i.e. ‘ ‘, ‘+’, etc). Sadly I cannot find this document anymore, so I cannot quote it, but the gist was that one of them converts spaces into ‘+’ signs, which the other treats as an actual plus sign, or something like that…
As such, I’m looking for a Javascript function that can take a string and make it URL-safe, and which has a perfect reversal function in PHP so that the original string can be recovered.
The arguably awful code I currently use to achieve this:
login.onsubmit = function(){
loginFailMsg.style.display = 'none';
var inputs = login.getElementsByTagName('input');
var formdata =
'username='+inputs[0].value+'&password='+encode(inputs[1].value);
submit.src = formtarget+'/auth/bklt?'+formdata;
userinfo = undefined;
setTimeout(getUserinfo,300);
return false;
};
Where’s
encodefunction coming from? Seems to me the quick answer to your question is usingencodeURIComponent()instead, available since JavaScript 1.5. See also Comparing escape(), encodeURI(), and encodeURIComponent(); it does not encode everything either, but does encode all the server expects it to.(As for cross-domain AJAX POST calls, I’d really have a look at “JSON with Padding”. See JSONP with jQuery that I mentioned in the comments earlier. This will also prevent issues with the
timeoutyou’ve randomly chosen, and jQuery will also help you, a lot, to get rid ofinputs[0].valueand the like. And, as you apparently already have a MD5 hash on the server, I’d really hash the password client side as well –see Karl’s answer— and compare those hashes instead. Respect your user’s password and your own time, drop that no external libraries requirement!)