Weblogs: Javascript

Fixing the back button that AJAX broke

Tuesday, January 03, 2006

One of the common disadvantages of AJAX is that it typically breaks the expected back button functionality. AJAX breaks one of the fundamental rules of the World Wide Web: one URL refers to one resource/document. There are three main stumbling blocks created by this development approach:

Clicking back from an AJAX page

You've surfed to an AJAX powered page, and after a number of page updates you click on the back button. This currently takes you to the page immediately before the AJAX page in the browser history.

People are expecting that hitting the browser's Back undoes the last AJAX page update, especially when the last AJAX request fundamentally changed the page. For instance, in GMail, starting from the Inbox, clicking on an email results in the contents of the selected email being displayed. Clicking on the browser's back button at this stage, and people expect that the Inbox will be redisplayed - and not the previous page currently sitting in the browser's history (like the GMail login screen).

It's a change of view, and the browser user associates this change as the same as moving from one HTML page to another. In terms of typical web browsing, this is a well-understood feature. AJAX breaks this feature.

Clicking forward to an AJAX page

After mistakenly clicking on the browser's back button, a typical user knows that clicking on the forward button should take them right back to where they were.

But in an AJAX document, the end result is that the user is taken back to the very first version of the AJAX document, and its missing all the changes the user has done before he mistakenly hit the back button. This is an unexpected occurance, and poses another usability barrier.

Is AJAX a web document or a web application?

Part of the AJAX problem is understanding whether an AJAX enhanced page is actually a web application, or is it still just a web document? I'm inclined to agree with Jeremy Keith, in his blog post Hijax, where he opines: Web applications and web pages are not mutually exclusive. One is built on top of the other.

Web applications have been around before AJAX was christened. Even before Microsoft invented XmlHttpRequest. Outlook Web Access before XmlHttpRequest used frames - and ran into a number of usability and accessibility issues.

Breaking the fundamental assumption of the Web

What's fascinating to see is that the usability and accessibility problems of AJAX applications are very similar to the usability and accessibility problems of frames. The fundamental problem with both techniques is that they break the major assumption of the World Wide Web - one URL refers to one resource. A URL of an AJAX page is similar to a URL of a frameset - they both disguise the true locations of resources.

When one URL points to a resource, typing the URL into your browser retrieves that resource. AJAX breaks this assumption - when an AJAX request changes the document in the browser we essentially get two documents. The original document and the changed document. The changed document does not have its own URL, because it doesn't really exist as a document in its own right - it is the amalgamation of one document and a piece of JavaScript - its a virtual document, only really existing in the browser.

The problem occurs when the user expects both documents to be retrievable - one is an Inbox view, and the other is the contents of an email. Both documents are full documents in their own right, one is addressable at a URL, and the other isn't. The second document (the contents of the email) does not replace the original document (the inbox view) at the URL, but it can only be retrieved via the same URL as the first document.

And that explains why the back button is broken. If you start from a URL, and click a link to another URL, its possible to navigate backwards and forwards between the two documents. Because they are at two different URLs. In the AJAX world, both documents have the same URL: there's the start document, and the new document created on the fly through a DOM change - but they are at the same URL. We can't navigate between the two documents, because the first URL is the start page, and so is the second URL. Since both URLs are the same, the assumption is made that they are the same document, so there's no point adding it the the browser history.

Bookmarking AJAX pages

When you bookmark a page in a GMail application and revisit it later, which version of the document do you expect to get back:

Currently, bookmarked AJAX applications return the first document, but the user typically expects it to return the document as it was when bookmarked.

Working towards a potential solution

If each document created by an AJAX application can be addressed by its own URL, then we can conceptually solve the broken back button problem (and the bookmarking problem to boot). If you can address the GMail Inbox view by one URL, and the contents of the selected email at a different URL then we have the expected situation of one URL referring to one resource document.

An AJAX document is built up from a starting document, plus a number of DOM manipulations to add, remove and change the nodes in a document. The end result is a URL plus a number of DOM manipulations. To retrieve the end resulting document we have to start from the starting document's URL, and apply all the DOM changes previously made before we get the end resulting document back again.

Start Document's URL + DOM changes = End Document

We can easily assign a URL to the end document. The difficult part is making sure that if that URL is requested, the browser ends up with the correct end document. This can be done in three ways:

Fixing the browser history object

Solving the addressability issue goes a long way to solving the navigation and bookmarking issues of an AJAX document. But its not a complete solution. Browser vendors need to update their browsers so that JavaScript can modify the history object of a browser.

When JavaScript modifies a document, it should be able to add a new item to the browsers history, and store the current document in the browser's cache (storing the state of the current document). At this point, two documents are available - the starting document, and the document after JavaScript has modified it. The URLs used to store these documents in the browser cache should be valid enough that if the cache is cleared, then requesting the URL should still be able to retrieve the document by one of the three methods outlined above.

There's a number of security issues arising from opening up the history object in this way. These need to be carefully weighed to prevent malicious use.

Related reading


[ Weblog | Categories and feeds | 2011 | 2010 | 2009 | 2008 | 2007 | 2006 | 2005 | 2004 | 2003 | 2002 ]