An important lesson learned about AJAX and accessibility

Published on Tuesday, April 25th, 2006

Yesterday I went to visit some fellow consultants at their assignment for a sub company/department of one of Sweden’s largest banks. We had a talk about AJAX in general and different ways of how to implement it, and one of them opened his web browser to navigate to some AJAX-based web sites.

Something interesting followed next that really baffled me. Most web sites he went to had empty white patches where no content showed up, and some web pages even went completely blank. We knew for sure that JavaScript was enabled in his web browser of choice (IE, but still almost a real web browser… ;-)) so that couldn’t be the problem.

Then, naturally, we had to go test my ASK script to see what was going on. The version that we got there was the fallback version that works without JavaScript, but instead with regular links reloading the entire web page, meaning that no JavaScript events were applied.

After some digging, we found out that the JavaScript file was completely blank! The reason for this, apparently, is that the proxy server they had to go through to access internet totally cleansed any JavaScript file that contained this text:


	new ActiveXObject

So much for object detection and every other approach we recommend to web developers. Not a single line of code was left behind in the file. And the problem is that it won’t throw an error or show the content of a noscript tag either; everything just stops working.

My initial reaction was that if they have such a tight security environment doing that, I really don’t want to care to cater to them. But as my boiling blood got calmer (kind of an exaggeration), I realized that this company was too big to ignore the fact that all their users got shut out.

Also, if they have a situation like this, it’s likely that many other large companies have a similar solution.

Conclusion: if you want to develop AJAX apps, make sure that it works without JavaScript as well, apply all the scripts in an unobtrusive fashion. I’m just glad that ASK passed the test with its accessible groundwork and then building AJAX functionality on top of that (Actually, the Google Analytics code of the ASK page did in fact throw an error when we tested it, but I think it was just a consequence of the proxy server doing it’s job…).

16 comments

  • Marco
    April 25th, 2006 at 12:49

    Hmm… this is an interesting issue indeed. It introduces a lot of problems on pure AJAX applications that for whatever reason don’t allow a non-JS version. A good example is a BackBase powered pure AJAX web application.

    I’ve seen those break horribly because of filtering proxies as well. Like you said, the noscript stuff won’t work either because JS is actually enabled on the client.

    I guess it may be worthwhile to look for a way to detect whether a filtering proxy is present or not, possibly by a piece of JS that won’t get filtered out which detects the lack of certain other code….

    Just thinking out loud here… :)

  • Chris
    April 25th, 2006 at 14:04

    But what can you do in fact against such problems? I mean, you can’t foresee how a client machine or network filters your Javascript. Therefore you’ll have to wait and react when an error occurs.

    Or did I just misunderstood?

  • Robert Nyman - author
    April 25th, 2006 at 14:04

    Marco,

    My thoughts have been similar to yours…

    To have some kind of variable or so that’s initially false, but it gets set to true in the JavaScript file that contains the AJAX functionality.

    I guess it’s good practice then to separate the XMLHttpRequest code into its own file, as not to ruin any other scripts in the web page.

    Chris,

    No, you understood me correctly, and it’s a valid question.
    My gut feeling is the approach mentioned above, to separate AJAX functionality into its own file, and to maybe also use varibles to set and check if they exist to make sure everything will work as intended.

    Also, when possible, to have a proper fallback if the necessary JavaScript support isn’t there.

  • Faruk Ates
    April 25th, 2006 at 14:31

    Ah, the wonderful hell that is clueless or violent proxy filtering.

  • Montoya
    April 25th, 2006 at 15:32

    Fortunately I’ve been able to make my latest project with Progressive Enhancement… but doing this is very difficult. I’m finding it hard to see how an application could be implemented with unobtrusive AJAX and still be infinitely-scalable. Maybe I’m just not experienced enough to see it.

  • Jules
    April 25th, 2006 at 15:46

    Interesting!

    Therefore, to ensure that your site/application works, you must test all JS-capable browsers, older JS browsers (to verify graceful degradation), current but JS-disabled browsers, and current JS-enabled browsers with empty JS-files.

    Or, don’t bother with JS because it is just too complicated. :-)

  • Robert Nyman - author
    April 25th, 2006 at 17:59

    Faruk,

    Yes, isn’t it great? :-)

    Montoya,

    I’m finding it hard to see how an application could be implemented with unobtrusive AJAX and still be infinitely-scalable.

    I guess it depends on the application. Not every application can offer a perfect matching fallback with JavaScript, but as far as possible, it’s a good goal to have.

    Jules,

    Or, don’t bother with JS because it is just too complicated.

    No, no, no. :-)
    JavaScript is amazing when used right (and in the absence of terrible proxy filters… :-)).

  • Jeena Paradies
    April 25th, 2006 at 18:26

    Oh that’s cool, I just set up my proxy to filter all files including the text javascript ;-)

  • Tanny O’Haley
    April 25th, 2006 at 19:27

    Instead of using ActiveX to initiate the xmlhttprequest object for Microsoft, how about trying the proprietary XML element?

  • Jakob Heuser
    April 26th, 2006 at 10:39

    Having looked at this before, we’ve used a very (cheap) load notifier which was placed at the end of each externally loaded js file:

    filename = "myfile.js";
    if (typeof ld_scripts != 'object') ld_scripts = new Object();
    ld_scripts[filename] = true;

    Upon the included file being loaded, you can always check ld_scripts and make sure everything you need filewise has made it intact.

    In our case, we were using it to ensure that all scripts loaded via document.write() had actually completed before we tried to reference objects and classes in those external files.

  • Robert Nyman - author
    April 26th, 2006 at 16:05

    Jeena,

    Ha ha. :-)

    Tanny,

    I haven’t tried it out, but I guess that might work. Not sure, though…

    Jakob,

    Yes, that’s the kind of approach that needs to be done.

  • Markus Dresch
    April 26th, 2006 at 19:48

    what about eval(”new Active” + “X” + “Object(…)”)?

  • Hakan Bilgin
    April 27th, 2006 at 5:05

    This is rather old news yet topical; XML islands.

    Dean Edwards has recently wrote something about this.
    XML Islands

    But with XML islands, it’s not possible to utilize the POST-method…

    /hbi

  • Robert Nyman - author
    April 27th, 2006 at 10:37

    Markus,

    Not sure, actually…
    And unfortunately I don’t have any good environment to test. I like the creative thinking, though! :-)
    It just might work!

    Hakan,

    Well, that might be an alternative fallback option, but , like you say, then we miss out on some functionality.

  • FACTA ET VERBA » recursos y mas recursos AJAX
    July 14th, 2006 at 16:09

    […] ne of a ticker script automatically, while the user is trying to read other content? Nope. […]

  • How to hide and show initial content, depending on whether JavaScript support is available - Robert’s talk - Web development and Internet trends
    May 13th, 2008 at 23:17

    […] tells you if JavaScript is enabled or not in the web browser; not if it actually works. There are proxy servers out there cleaning out JavaScript files with what it thinks is inappropriate content, over-zealous antivirus programs, firewalls preventing […]

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

All the proceeds from ad clicks will go to charity. However, if you like to give something directly to charity yourself, I recommend choosing from the listed ones below.

  • Save the Children
  • Red Cross
  • Cancer Research UK
  • WWF

Top results