Geekery

If you’re having issues with getting some AJAX to work in Chrome or the newer Safari versions, then I hope this post will hope you.

This issue arose when one of our designers was testing some of the new AJAX I had written in Chrome. It worked fine in Firefox and IE, but Chrome was choking on the XML that was coming back. Treating it as though it were equal to null and alerting the appropriate response that is written in to our AJAX JavaScript. A bit more testing revealed that Safari was also having the issue. Once we figured that out, it became evident that searching for issues with WebKit would help.

Both browsers use the WebKit application framework. Because of this, they both enforce (choke) on XHTML that is given to them which does not follow the standards of XHTML. One of these standards, is that virtually all HTML entities are not valid. Here are the three that are:

 
<
&rt;

All other html entities need to be converted to their XML-safe (ASCII) form. So:

˜ = ñ

This can mess up AJAX that works in Internet Explorer and Firefox because they don’t mind dealing with XHTML coming back from an AJAX response with HTML entities. If you’re passing complicated strings with any entities in it through your AJAX requests, don’t expect them to work with any of the browsers using the current WebKit framework.

It took me a while to figure out what was causing the issue that our testers were experiencing, but once we did some searching, we found that others have talked about having this, or a similar problem, too.

We had experienced an issue with foreign characters creating improper RSS feeds for the same reason: html entities showing up when they shouldn’t be. I researched and wrote a function then that would convert all the HTML entities to their numeric format that would be safe. I applied this function to the AJAX responses coming back and presto, it worked.

So, I thought I would share this function with everyone in case someone else was having a similar problem:

function clean_string_for_valid_xml($string) {
    $entities_array = array();
    foreach (get_html_translation_table(HTML_ENTITIES, ENT_QUOTES) as $character => $entity) {
        $entities_array[$entity] = '&#' . ord($character) . ';';
    }
    return str_replace(array_keys($entities_array), $entities_array, $string);
}

Basically, we’re using the get_html_translation_table function to grab all of the entities. Then, we’re using the ord function to get the ASCII value for those entities. Then, we’re returning our string with the entities properly replaced.

Hopefully this works for you, or at least leads you to an answer that works for you.

If you liked this post, then please consider subscribing to my feed.