IE adds encoded values to encodeURIComponent in every AJAX call - php

I am passing a value for example "Cats & Dogs" through a AJAX request.
I am applying encodeURIComponent to the value like: encodeURIComponent("Cats & Dogs");
Then I set the browser hash to this value for AJAX bookmarking. It works well in Firefox - in the the hash it appears as #value=Cats %26 Dogs, however in IE it appears as Cats%20%26%20Dogs, this causes a problem when I attempt to read the hash and resend it in a AJAX call, IE keeps adding more encoded values so the previous value becomes Cats%2520%2526%2520Dogs and then Cats%2520%2526%2520Dogs and so on...
This does not occur in Firefox.
How can I overcome this issue?

Nevermind, I found my problem. I was not decoding the encoded value before setting it as the hash.

Related

Why does PHP replace pluses with spaces in $_COOKIE?

So from my understanding of PHP and cookies, if I use the setcookie() function, then I get a cookie that is automatically url encoded. And when I go to the $_COOKIE array, I should get the cookie back, automatically url decoded. Problem is, it seems to be decoding the cookie twice when I look in $_COOKIE.
Say I have a cookie whose value is "Name|ID|Email", for example:
Joe|123|my+email#somewhere.com
This would be encoded as:
Joe%7C123%7Cmy%2Bemail%40somewhere.com
Notice the plus sign is encoded, so theoretically I ought to get it back if I decode it. Since this is automatically done in $_COOKIE, I ought to get back what I started with. But instead, I'm getting back:
Joe|123|my email#somewhere.com
Notice the space where the plus used to be. This is what I would expect if I ran an additional urldecode() on the cookie. But I'm not, so I have no idea why I would be getting a space instead of a plus.
Another interesting twist. A refresh on the page seems to produce the correct output. Any ideas why it's behaving like this?
FYI, to set the initial cookie, I use javascript and escape() the script to produce the encoded string. Might this be an hand off issue between javascript and PHP?
Thoughts would be appreciated.
It's worth noting that both "%20" and "+" are valid encodings of a space character. Per the Wikipedia article on URL encoding (emphasis added):
When data that has been entered into HTML forms is submitted, the form
field names and values are encoded and sent to the server in an HTTP
request message using method GET or POST, or, historically, via email.
The encoding used by default is based on a very early version of the
general URI percent-encoding rules, with a number of modifications
such as newline normalization and replacing spaces with "+" instead of
"%20". The MIME type of data encoded this way is
application/x-www-form-urlencoded, and it is currently defined (still
in a very outdated manner) in the HTML and XForms specifications.
More specifically related to PHP and JavaScript, see the top answer on this question:
When to encode space to plus (+) or %20?
Firstly, PHP will always run before JavaScript - it's server side rather than client side so the cookie you set with JavaScript won't actually be available to PHP until you refresh the page (hence that issue).
Next JavaScript has different ways to encode the strings; only one will work with PHP automatically.
So:
document.cookie = "testuser=" + "Joe|123|my+email#somewhere.com";
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + escape("Joe|123|my+email#somewhere.com");
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + encodeURI("Joe|123|my+email#somewhere.com");
// Joe|123|my email#somewhere.com (when decoded by PHP)
document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email#somewhere.com");
// Joe|123|my+email#somewhere.com
So, try this for the sake of a test (remember you'll need to refresh the page to see the cookie value):
<html>
<head>
<title>Cookie Juggling</title>
<script type="text/javascript">
document.cookie = "testuser=" + encodeURIComponent("Joe|123|my+email#somewhere.com");
</script>
</head>
<body>
<div><?php echo !empty($_COOKIE['testuser']) ? $_COOKIE['testuser'] : "Cookie not set yet"; ?></div>
</body>
</html>
If you don't want to automatically encode the cookie, you can use setrawcookie function.
The exception with this function is, you can not use these characters: (,; \t\r\n\013\014) :
setrawcookie("NAME","Joe|123|my+email#somewhere.com");
# Output in browser:
Joe|123|my+email#somewhere.com
# Output in PHP `echo $_COOKIE['NAME']`:
Joe|123|my email#somewhere.com
Tested with PHP 5.3
setcookie("NAME","Joe|123|my+email#somewhere.com");
# Output in browser:
Joe%7C123%7Cmy%2Bemail%40somewhere.com
# Output in PHP echo $_COOKIE['NAME']`:
Joe|123|my+email#somewhere.com
now : As an alternative way, you can use setcookie(), and rawurldecode() to decode it:
echo rawurldecode($_COOKIE['NAME'])

Not using & when POSTing to php

I'm building a very AJAX site which means posting a lot of information to the server, sometimes typed by a user.
this is how I'm posting things
xmlhttp.open("POST", 'somepage.php' ,true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send('post=stuuf I want to send');
An example of my problem is this, someone types FOO BAR as their name which would post firstName=FOO&lastName=BAR
which in php gets you $_POST['firstName'] is FOO and $_POST['lastName'] is BAR
but if someone types the name FOO&BAR SMITH it would post like this firstName=FOO&BAR&lastName=SMITH
which in php gets you $_POST['firstName'] is FOO and $_POST['BAR'] which has no value and this start to fall apart. It means I have to replace & in everything that is posted and I'm finding it annoying.
Is there a way to tell php to ignore any &, and just send one big string. when I need to send multiple values I was planning to break them up with an '_' I could then replace any user typed _ with &#95 and never have to worry about it again.
Could this be done in .htaccess or if not then in the php file itself?
Thanks for any help
Don't do this on the PHP end... send a proper HTTP request! You are mangling all of your data client-side. If you're sending URL encoded data, send it URL encoded.
No, but you absolutely must escape your data before using it as a string inside the ajax request.
You should encode the data you want to sent using encodeURI or encodeURIComponent. That way you can send whatever characters you want.

How to ensure variables submitted in UTF8 using jquery $.post

I have been struggling with this for three days now and this is what i have got and i cannot understand why i am seeing this behavior.
my problem is that i have a MySql spanish db with char set and collation defined as utf8_general_ci. when i query the data base in delete.php like this "DELETE FROM countryNames WHERE country = '$name'"
the specified row doesnot get deleted. i am setting the variable $name in delete.php through a post variable $name=$_post['data'] . mostly $name gets the value in spanish characters e.g español, México etc. the delete.php file gets called from main.php.if i send a post message from main.php $.post("delete.php", {data:filename}); , the query doesnot deletes the entry (although the 'filename' string is in utf8) but if i create a form and then post my data variable in main.php, the query works!! the big question to me is why do i have to submit a form for the query to work? what im seeing is my database rejects the value if it comes from a jquery post call but accepts it when its from a submitted form. (i make no code change for the query to work. just post the value by submiting the form)
First of all, to see what charset ìs used for requests, install something like Firebug and check the 'Content-Type' header of your request/response. It will look something like 'application/json; charset=...'. This should be charset=utf-8 in your case.
My guess why it worked when posting a form is probably because of x-www-form-urlencoded - non-alphanumeric characters are additionally encoded on the client side and again decoded on the server, that's the difference to posting the data directly.
This means that somewhere there is a wrong encoding at work. PHP treats your strings agnostic to its encoding by default, so I would tend to rule it out as the source of the error. jQuery.post also uses UTF-8 by default... so my suspect is the filename variable. Are you sure it is in UTF-8? Where and how do you retrieve it?
You should probably also ensure that the actual HTML page is also sent as UTF-8 and not, let's say iso-8859-1. Have a look at this article for a thorough explanation on how to get it right.
guys this was a Mac problem!! i just tested it on windows as my server and now everything works fine. So beware when u r using Mac as a server with MySql having UTF8 as charset and collation. I guess the Mac stores the folder and file name in some different encoding and not UTF-8.
You answer might be here: How to set encoding in .getJSON JQuery
As it says there, use $.ajax instead of $.post and you can set encoding.
OR, as it says in the 2nd answer use $.ajaxSetup to set the encoding accordingly.
Use .serialize() ! I think it will work. More info: http://api.jquery.com/serialize/

How do I escape '+' in data I’m sending via AJAX in Mootools?

I was building a simple web based calculator which takes equations from a HTML form, evaluates it on the server using PHP and sends the result back.
I am using Mootools to send the data via the req.send AJAX operation.
But, each time I have a '+' in an equation, it is not seen on the POST data the server gets.
Any ideas why this is happening and how I can work around it?
eg:
10 + 12 in HTML form is seen as 10 12 in the $_POST data.
The Mootools send command I am using is something like this with
<textarea name="equationTextArea">10+12</textarea>
req.send("eqn="+$('equationTextArea').value);
Upon submit, I see $_REQUEST['eqn'] as 10 12.
Try using the function encodeURIComponent over your text value. It, well.. uri encodes your text.
Set your form's encoding to multipart/form-data - this is an alternative to the default application/x-www-form-urlencoded and doesn't encode a space into a plus sign +.
Example from the w3.org reference:
<form action="http://example.com/cgi/handle"
enctype="multipart/form-data"
method="post">
Your text most likely either need to be URLEncoded.

PHP form auto escaping posted data?

I have an HTML form POSTing to a PHP page.
I can read in the data using the $_POST variable on the PHP.
However, all the data seems to be escaped.
So, for example
a comma (,) = %2C
a colon (:) = %3a
a slash (/) = %2
so things like a simple URL of such as http://example.com get POSTed as http%3A%2F%2Fexample.com
Any ideas as to what is happening?
Actually you want urldecode. %xx is an URL encoding, not a html encoding. The real question is why are you getting these codes. PHP usually decodes the URL for you as it parses the request into the $_GET and $_REQUEST variables. POSTed forms should not be urlencoded. Can you show us some of the code generating the form? Maybe your form is being encoded on the way out for some reason.
See the warning on this page: http://us2.php.net/manual/en/function.urldecode.php
Here is a simple PHP loop to decode all POST vars
foreach($_POST as $key=>$value) {
$_POST[$key] = urldecode($value);
}
You can then access them as per normal, but properly decoded. I, however, would use a different array to store them, as I don't like to pollute the super globals (I believe they should always have the exact data in them as by PHP).
This shouldn't be happening, and though you can fix it by manually urldecode()ing, you will probably be hiding a basic bug elsewhere that might come round to bite you later.
Although when you POST a form using the default content-type ‘application/x-www-form-encoded’, the values inside it are URL-encoded (%xx), PHP undoes that for you when it makes values available in the $_POST[] array.
If you are still getting unwanted %xx sequences afterwards, there must be another layer of manual URL-encoding going on that shouldn't be there. You need to find where that is. If it's a hidden field, maybe the page that generates it is accidentally encoding it using urlencode() instead of htmlspecialchars(), or something? Putting some example code online might help us find out.

Categories