Saturday, January 07, 2006

Dynamic web applications and disabling browser's "Back" and "Forward" buttons.

Introduction:
I have recently read several good articles talking about problems with browser's "Back" and "Forward" buttons on AJAX, and, speaking in more general terms, any web pages with a dynamic content. Basically: when user clicks one of these buttons browser loses document's state. So, it is not possible to go back. It's perfectly described in isolani's article.

It's a long known problem with pages with frames, dynamic PHP/ASP pages using session variables, etc. People discuss various possibilities to save a state in browser's history/cache and for AJAX commands to add entries into history/cache. I believe that as this problem has only one radical solution: a web browser should allow HTML document to conditionally disable "Back" and "Forward" buttons.
Such dynamic web pages are not plain but rather web applications - speaking in isolani's terms. And an old web ideology which restricts from doing that does not apply to such pages.
Not everybody knows that Internet Explorer already allows to control these buttons in a indirect way with its onbeforeunload() event.

Again, here are several articles when people desperately try to resolve these issues:
Fixing the back button that AJAX broke
Hijax
Back button and Undo in Ajax applications
public-webapi@w3.org - Ajax Back/Forward History problem – saving document state

I sent a couple of messages in reply to this lists.w3.orgdiscussionn - not sure when and where they will appear. So, below is a copy of these messages:

***************
In reply to Karl Pongratz's message I said the following:

Karl Pongratz wrote:
> I also want to note that I wanted to propose something
> simple that solves the emerging Ajax web application web
> browser history problem, something that is strongly tight
> to the xmlhttp request object and would be easy to
> implement by user agent vendors.

Karl, I strongly believe that modifying browser's engines to save *state* in addition to URL just cannot be simple enough. I highly doubt it would be implemented any soon.

As says here, "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 believe that an AJAX enhanced page should be considered a web application by itself. I also believe, that the best and really easy solution would be to conditionally disable "Back" and "Forward" buttons on an AJAX page. When I said "conditionally" I meant that in case a user clicks one of these buttons a browser should display a confirmation window asking if user really wants to *leave application*.

Yes, it would break a "pure HTML ideology", but this ideology applies to web pages, not to web applications.

AJAX web pages aren't first pages which would benefit from conditionally disabling "Back" and "Forward" buttons. The same issue arises for any web pages with dynamically modified content: for pages with frames, for pages with Java applets or ActiveX controls.

Even plain HTML pages generated by server-side (PHP, ASP, etc.) script often experience troubles with "Back" and "Forward" buttons. Consider a standard situation when a page uses HTML form to POST to itself, or when server-side script uses SESSIONS to save data on a server side. It immediately breaks a normal behavior of "Back" and "Forward" buttons, because document's *state* is not exclusively determined by a URL, it may depend on a session variable or even data, retrieved from a database.

So, again, such pages are web applications by themselves - something similar to a graphical Windows desktop application, and they should be able to restrict "Back" and "Forward" buttons' behavior.

Internet Explorer does provide a way to do it with onbeforeunload Event.
Unfortunately, other browser's vendors consider themselves more "purist" and do not provide such ability. If you try to Google like this you'll get a long list of messages from people struggling to disable those buttons... I understand that controlling "Back" and "Forward" buttons' behavior from a loaded HTML document may introduce some security risks, but I think that it well worth to implement as standard behavior - advantages are immense.

***************
In reply to Garret Wilson's message I said that:

Garret Wilson wrote:
> Web applications are truly applications, and it may be
> correct for them to expose certain commands to their
> runtime container (which may be a browser)

I think that you words apply perfectly to "Back" and "Forward" browser's buttons which should be controllable to certain degree by HTML document itself. If properly implemented, it would solve a lot of problems with dynamic web pages (like pages using AJAX) being not compatible with "Back" and "Forward" buttons - because they lose their state when browser leaves a page.

See Ajax Back/Forward History problem thread here and/or here.
Also take a look at Ajax Mistakes topic SourceLabs forum.

***************
After thinking about this issue and reading more articles I understood, that we should distinguish two different situations of using "Back" and "Forward" buttons:
1) To Enter/Exit current web application.
2) To travel inside current web application.

All my words above about conditional disabling of buttons apply to 1).
In 2) "Back" and "Forward" buttons are a convenient tool. I recently found an article written by Mike Stenhouse and called Fixing the Back Button and Enabling Bookmarking for AJAX Apps. It does allow to use navigation buttons inside AJAX application. But despite the fact that it's a clever code, I consider it as a hack. Just too much smart efforts for such a simple and common thing.
I wonder why it is considered better to have navigational buttons provided by a container (web browser). Coming from a windows desktop applications background (VB/Delphi) I would say, that it is oftensimplerr and more flexible to control navigation inside an application using its own tools. Speaking about web application, I would say that it is often better todisablee "Back" and "Forward" buttons inside application and to use application's custom buttons/links to go back and forth.
Unless some major changes are incorporated into modern browsers allowing to track changing state by means of AJAX.