Fixing the back button that AJAX brokeTuesday, 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
- Clicking forward to an AJAX page
- Bookmarking a document created by AJAX
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.
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:
- The start page of the AJAX application
- The Inbox view
- The document exactly as it was when the URL was bookmarked
- The last document seen at that URL
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:
- The server-side script handling a request of the End Document URL returns a document which matches the End Document (without needing to access the Start Document).
- The server side script starts with the start document, and applies all the necessary DOM changes to get to the End document and returns that to the browser
Fixing the browser history object
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.
- Back button and Undo in Ajax applications
- Content with style: Fixing the Back Button and Enabling Bookmarking for AJAX Apps
- Alex Bosworth: Ajax Mistakes
- W3C Web API Thread: Ajax Back/Forward History problem - saving document state by document.save()