The Back Button Problem of AJAX applications



 A lot of people already wrote about this topic. Search "AJAX BACK

BUTTON PROBLEM" on a search portal and you can find a lot of stuff about
it!
But there are still aspects that haven't been talked about a lot.
Let me explain that the problem is old, well known, not an AJAX specific
problem and after all: technically solved.

What the back button does - and why not
Still some people think that the web is a mass of pages pointing to each other
using hyperlinks. While navigating along these hyperlinks every visited page
is recorded into a local list often called "history". The original idea was to
support this list of pages with some functionality.
When framesets came into the browser model this simple idea got the first
scratch because when you use hyperlinks that change only the content of a
frame the url doesn't change. The url that you can see in the address is not the
only information you need to restore a browser situation.
Up to here the back button still works in the browsers, because they also
record this extra information together with the url - at least when working
with the browser history functionality.
Then there are web servers that found a (not so) wonderful trick to use forms
for navigating from one page to another and things get complicated.
Hyperlinks can be used to submit the content of a form (including the current
browser state) back to the server which then returns the next or the modified
page. A problem on this approach is that the same url (main.do, main.aspx,
main.jspx, main.php, ...) can be reused for the whole application.
Here the back button also has to record all the data that was posted to the
server so it can be re-posted when the user wants to go one or more pages
back.
This kind of request cannot in generally be distinguished by the server from
clicking the same button of a form twice and often there are filters available
on the server to redirect these requests to another page.
And this is why navigating back using the back button of the browser often
doesn't work.
And this is why many applications start a new window at the beginning
without displaying the navigation bar that includes the back button.
And this is why many users like the back button on the mouse or keyboard
(ALT-LEFT).
And this is why the web doesn't work like this (too often).

The favorite problem
As with the history list a very similar problem exists with the favorites and
with web urls stored in files. When you save a current page to your favorites
list you might think that this helps you coming back to this page but if the
server needs post information or the page is built using frames you might
become disappointed because this kind of information is not stored in
hyperlinks.
The IE implements a special *.url file type that is created when using the IE
built in "Add to favorites..." command that contains extra information about
the current urls of the frames and maybe more.
But the *.lnk file type that is created when dragging an URL from the IE
address bar to the desktop as well as the url file that is created by
Mozilla/Firefox doesn't hold this information.
What's the problem?
The problem with the back button existed long before AJAX applications
became widely known. The core of the problem is about building a web
application that works by using meaningful urls whether using frames or not
and enabling the usage of the history and favorites feature of the existing
browsers.
AJAX applications do have the same problem like those applications doing
everything through a single url: it's meaningless and you cannot rely on any
posted information because it just doesn't exist.
So what we all have to do is giving our applications meaningful urls.

Meaningful urls
Not every click should change the url and in many applications there is no
clear "back" situation. If you browse your mail inbox for example a click to
open a message may be a clear "navigate to" situation. When you delete the
message by using a click on a button the main UI might navigate for you to
the next message in the list. But where is the "back" position now - on the
deleted mail?
You can also argue that moving on to the next mail is neither forward nor
back but something like up and down and back will always bring you back to
the list view you started.
So what I want to say is that the (forward and) back direction is often very
application or problem specific. With AJAX you have the chance to model
these situations the way you like and the way that is the best for your
application and you are not bound to the GET and POST requests done by
hyperlinks and forms.
I use the url as a textual key to the global addressable state of an Ajax
application. By moving some information into the url and reading this
information out of the url when a page loads or the urls changes, there is a
clear interface between the Ajax page and the external world that can be used
for storing browser history, favorites and links.
The back problem is technically solved
If you look for a good article on how to implement a technical solution to the
problem have a look at the article "AJAX: How to Handle Bookmarks and
Back Buttons" by Brad Neuberg
http://www.onjava.com/lpt/a/6293.
... by tricking IE
The Mozilla/Firefox solves this problem really straight forward and it works
as expected.
When using the method window.location.replace(newHash) only the current
URL is changed.
By assigning a new value to the window.location.hash property a new entry in
the history list is created.
The IE is very confused about URL-hash values hat do not really point to
existing anchors and does not record any history and needs an invisible iframe
with a page coming from the same server. It's a little bit tricky to get all
situations working and you can see the current implementation by looking
into the JavaScript implementation of the PropHistory Behaviour. Have a look
at the source:
http://www.mathertel.de/AJAXEngine/ViewSrc.aspx?file=~/controls/PropHistory.js

An Implementation
The AJAXEngine already has a client side state mechanism (Page Properties
or DataConnections) I introduced in September 2005 that stores key-value
pairs. Instead of building a new API and leave it to the AJAX application to
call a method to change the URL you only have to declare what page
properties should be used in the URL. When a Page Property's value changes
the URL is updated automatically and when the URL changes all connected
controls will get informed about it.
When one of the properties, that define a state that should be persisted to the
history changes, a new history entry is recorded.
All you need to do to make it work is to include the PropHistory control:
<ajax:PropHistory runat="server" stateList="version,book,chapter" propList="vers" />
I've added 2 attributes to the PropHistory web control that can be declared to
avoid some scripting on the page:
stateList specifies the page properties that together form the current state of
the page. A change to the value of any of these properties will cause a new
entry in the history of the browser.
propList specifies the page properties that are persisted in the hash part of the
url so that hyperlinks will work.
The implementation takes care of the fact that all properties in the statList
must also be part of the url but you don't have to specify them again in the
propList attribute.
If you need some default-values that will be used when no values are given by
the URL then script them like this:
<script defer="defer" type="text/javascript">
// set default values:
jcl.DataConnections.Load("version", "luther1912");
jcl.DataConnections.Load("book", "1");
jcl.DataConnections.Load("chapter", "1");
jcl.DataConnections.Load("vers", "1");
</script>
The sample comes from the Bible reader application:
http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx
When you navigate through the verses of a chapter, only the URL gets
changed. The navigation to a new book, version or chapter a new entry in the
history stack is created.
You now also can use URLs to jump directly to some important content.
Donald E. Knuth likes reading any book chapter 3 verse 16 and specially
http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx#version=sf_kjv_strongs_rev
1b&book=43&chapter=3&vers=16
An important verse of the Da Vinci code story by Dan Brown is
http://www.mathertel.de/AJAXEngine/S03_AJAXControls/BiblePage.aspx#version=en_gb_KJV2000_1
&book=18&chapter=38&vers=11

Post a Comment

You're welcome to share your ideas with us in comments.

Previous Post Next Post