views:

208

answers:

4

I have a generic function that returns URLs. (It's a plugin function that returns URLs to resources [images, stylesheets] within a plugin).

I use GET parameters in those URLs.

If I want to use these URLs within a HTML page, to pass W3C validation, I need to mask ampersands as &

/plugin.php?plugin=xyz&resource=stylesheet&....

but, if I want to use the URL as the "url" parameter for a AJAX call, the ampersand is not interpreted correctly, screwing up my calls.

Can I do something get & work in AJAX calls?

I would very much like to avoid adding parameters to th URL generating function (intendedUse="ajax" or whatever) or manipulating the URL in Javascript, as this plugin model will be re-used many times (and possibly by many people) and I want it as simple as possible.

A: 
David Dorward
Pekka
In HTML 4.x, script elements contain CDATA so any ampersands should **not** be escaped (and the validator won't complain about unescaped ampersands). In attributes values they **should** be escaped, but browsers handle them correctly.
David Dorward
David Dorward
Thanks for the background info!
Pekka
A: 

When you have markup of the form:

<a href="?a=1&amp;b=2">

Then the value of the href attribute is ?a=1&b=2. The &amp; is only an escape sequence in HTML/XML and doesn't affect the value of the attribute. This is similar to:

<a href="&lt;&gt;">

Where the value of the attribute is <>.

If, instead, you have code of the form:

<script>
var s = "?a=1&b=2";
</script>

Then you can use a JavaScript function:

<script>
var amp = String.fromCharCode(38);
var s = "?a=1"+amp+"b=2";
</script>

This allows code that would otherwise only be valid HTML or only valid XHTML to be valid in both. (See Dorwald's comments for more info.)

Roger Pate
Yes, I am serving ampersands in becomes the start of the GET parameter). This of course shoots down my AJAX requests.
Pekka
He's right. You only needs to use ampersand for printing. You don't want to put ampersands when doing the requests with ajax. :)
Savageman
A: 

Try returning JSON instead of just a string, that way your Javascript can read the URL value as an object, and you shouldn't have that issue. Other than that, try simply HTML decoding the string, using something like:

function escapeHTML (str)
{
   var div = document.createElement('div');
   var text = document.createTextNode(str);
   div.appendChild(text);
   return div.innerHTML;
};

Obviously you'll want to make sure you remove any reference to DOM elements you might create (which I've not done here to simplify the example).

I use this technique in the AJAX sites I create at my work and have used it many times to solve this problem.

Ash
Thanks, but I am producing links using a central PHP function, so I will get there with less code by doing the escaping / unescaping there. I was just looking for a way to avoid having to do even that, as it's going to be a basic function for a framework.
Pekka
No worries it's even easier in PHP - I thought the problem was with the Javascript AJAX request itself.
Ash
+2  A: 

It seems to me that you're running into the problem of having one piece of your application cross multiple layers. In this case it's the plugin.

A URL as specified by RFC 1738 states that a URL should use a & token to separate key/value pairs from one another. However ampersand is a reserved token in HTML and therefore should be escaped into &amp;. Since escaping the ampersands is an artifact of HTML, your plugin should probably not be escaping them directly. Instead you should have a function or something that escapes a canonical URL so that it can be embedded in HTML markup.

Bryan Kyle
All right. So I won't get around escaping it somewhere. I had feared so. However, escaping it on the HTML side makes it easier. Thanks for the RFC groundwork.
Pekka