Discussions

News: Onjava Article: 'AJAX: How to Handle Bookmarks and Back Buttons'

  1. OnJava has published an article by Brad Neuberg on handling the back button and bookmarking in an AJAX application. These two issues are some of the most often cited problems with AJAX outside of application design. The article covers the use of the "Really Simple History" library to provide workable functionality for AJAX.
    "AJAX: How to Handle Bookmarks and Back Buttons" explains the significant issues that AJAX applications currently face with bookmarks and the back button; presents the Really Simple History library, an open source framework that solves these problems; and provides several working examples.

    The principal discoveries of the framework presented in this article are twofold. First, a hidden HTML form is used to allow for a large transient session cache of client-side information; this cache is robust against navigation to and away from the page. Second, a combination of hyperlink anchors and hidden iframes is used to intercept and record browser history events, tying into the back and forward buttons. Both techniques are wrapped with a simple JavaScript library to ease development.

    Note that the article mentions that Safari isn't supported (and provides links for why). However, this brings up the browser support issue yet again. Is this a critical failure point for AJAX?

    Threaded Messages (20)

  2. Safari doesn't really matter[ Go to top ]

    As long as the browsers with major market shares can be supported without too much difficulty I'd say no. That will be enough for most projects. Browser incompatibilities is still a very real issue, but I don't see it stopping the AJAX momentum. As the author points out Safari really doesn't matter for most of us - yet.
  3. Safari doesn't really matter[ Go to top ]

    Safari actually has low market share these days; most people on the Mac are moving back to Firefox. In addition, Safari has tended to be a follower rather than a leader when it comes to these things; they did not even have XMLHttpRequest support until GMail forced them to do so, months later.

    Brad
  4. simpler solution?[ Go to top ]

    What are the advantages of this solution over the one proposed by Mike Stenhouse :
    http://www.contentwithstyle.co.uk/Articles/38/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps

    Mike's solution does not require use an any additional third party libraries for managing browser history.

    Sanjiv
  5. Mike Stenhouse's excellent coverage of this topic included a demo showing how you can roll your own unique URLs. It's not entirely easy, and it's also browser-specific. The library mentioned in this article, as well as those from dojotoolkit and Backbase, are the way forward in this area: cross-browser toolkit that abstract all the nasty browser-specific details.

    Note that this area has a number of ideal requirements.
    * Unique URL for each state.
    * Should be able to open the URL to load app in that state. This must work even when the app's already open. (Which is tricky since the URL is manipulated using a hash (#) fragment identifier, and browsers don't reload when that changes.)
    * Back button takes you back to previous state, and not to previous application. (Which is tricky since IE doesn't consider changes to # as part of the history, hence iframes.)
    * After the user leaves your app, Back button from *next* application must take you back to most recent state of your Ajax app.

    You might think having a unique URL would be enough to get history right, but that's not the case due to various idiosyncracies.

    All of the above requirements are worth fighting for - they're fundamental to the way users assume the web works. These libraries are the way forward.
  6. great[ Go to top ]

    Thanks. This was exactly the respose I was looking for.

    Sanjiv
  7. This is a great article, history support for Ajax applications is an awesome achievement. At the same time I think that the importance of having full history for Ajax application is overrated.

    Take GMail. This is a typical CRuD application with item list and editing/viewing of a particular item. When you read a particular email, you don't see the list, so it is easy and convenient to return to the list using Back button. In this case usage of history is justified.

    In the O'Reily Mail you can see left navigation menu and content pane. You click Back and scroll to previous menu item. What for??? The menu is always visible. It is more convenient just to click on another menu item. Why would I want to go back and forward through a menu? I hate scrolling back and forth through meaningless pages, the nonsensical dead views of resources I visited a while ago.
    Note that this area has a number of ideal requirements.
    * Unique URL for each state.
    * Should be able to open the URL to load app in that state. This must work even when the app's already open. (Which is tricky since the URL is manipulated using a hash (#) fragment identifier, and browsers don't reload when that changes.)
    * Back button takes you back to previous state, and not to previous application. (Which is tricky since IE doesn't consider changes to # as part of the history, hence iframes.)
    * After the user leaves your app, Back button from *next* application must take you back to most recent state of your Ajax app.

    Why, oh why do you want unique URL for each state? This just pollutes browser history and makes writing of web wizards a complex and tedious task. A resource, not a state of the resource must have unique URL. I don't want to navigate to an arbitrary state or view of a resource, I want to navigate to resource itself, and to see the resource in its current state. This is what web is about, the resources, check HTTP spec.

    Back button, switching application states, is like tail wagging the dog, it does not make sense. Application state should be changed, based on input command and input data, not on something absolutely artificial to application. Browser history is a part of view at best, and it should not affect the model. Browser history is not a cache, it does not store stale views, it stores locations of visited resources.

    No one raises eibrows when they start, say, MS Word, and see a blank page, or a list of recent files at best. Why do you expect from a web application to record all your activities and state changes? Imagine MS Word with "Record Macro" turned on all the time. Yuck.

    I truly appreciate the technology described in the article, I just hope that it won't be used everywhere just because it can be, and because users got used to Back button. The latter just a white lie. No one likes to incorrectly submit a form five times, and then to click Back six times to get out of the page. Again, history and navigation is good, but entities that are being navigated should be meaningful. To create a great application a developer should consider every smallest use case, to decide how it should be handled.

    What I personally want to be able to do is to be able to refresh resource freely, and to have a webapp completely retained its state, with data, with selected items, with relative element positions, etc. Considering bookmarking, I would just mix and match traditional navigatable pages and Ajax, where a navagatable page identified a resource. I would be able to bookmark a resource with no problem. If I could use approach described in the article creating a fully ajaxified application, that would be even better, but I would not meticulously resurrect full session history in Ajax application.

    Ajax liberated us from session history, don't put yourself back into chains.
  8. yes, but..[ Go to top ]

    Yes, but users should see what they expect when they click the Back Button. We do not have control of the users and while we can argue that in many applications going through a menu item makes more sense than clicking the back button, a web application should not enforce it.


    No one likes to incorrectly submit a form five times, and then to click Back six times to get out of the page.


    In many AJAX based apps, all posts (except multipart uploads) are done using AJAX so when the user hits the back button, he is taken the the page that was fetched as a result of the previous GET - and this is logically what the users expect to see. I think that the use of AJAX for POST's effectively solves the Double Submit problem and one no longer needs to use patterns like "Post and Redirect".
  9. yes, but..[ Go to top ]

    Yes, but users should see what they expect when they click the Back Button.
    The users may expect a printer to print real bank notes or that recordable CDs contain real gold (I think they did long ago?). Users can expect a lot of things.
    In many AJAX based apps, all posts (except multipart uploads) are done using AJAX so when the user hits the back button, he is taken the the page that was fetched as a result of the previous GET - and this is logically what the users expect to see. I think that the use of AJAX for POST's effectively solves the Double Submit problem and one no longer needs to use patterns like "Post and Redirect".
    This is true. Redirect-After-Post is like a last-generation carburetor. No matter how refined it is, it cannot not provide a needed level of fuel efficiency, reliability and emission control. But it works everywhere, does not require Ph.D. in electronics and expensive parts to repair, and cannot be destroyed with electromagnetic gun ;)
  10. Michael, this is a long and well-thought out criticism. However, it depends on one base fact, whether user's depend on the back button. I believe the answer is yes, and usability studies back me up.

    I believe that one of the reasons Google was successful with DHTML, while previous companies have failed with it in the past, was because they used DHTML to create what appeared to be normal web pages but with enhanced capabilities. This is the secret to Google Maps and GMail; they look and feel like web pages, but are much faster and can offer improved UI controls because they live much more on the client side than previous web pages.

    I believe the secret to creating great AJAX applications is to fully accept that you are running within the browser, and to accept the conventions of the web. These include the ability to bookmark, the back and forward buttons, accepting the full browser chrome rather than using a popup window to hide them, etc. The Really Simple History is an essential step in making AJAX applications accept their context (when in Rome do as the Romans do...) The chains are there for a reason, just as in desktop applications the chain of consistent look and feel is there for a reason.

    Do I wish the browser had native support for the kinds of functionality RSH provides? Of course I do; I don't like having to take advantage of browser hacks to create something like RSH, but it's currently the reality of the web.

    Best,
      Brad
  11. Michael, this is a long and well-thought out criticism.
    Brad, thanks for not taking it personally.
    The chains are there for a reason, just as in desktop applications the chain of consistent look and feel is there for a reason.
    I thought that Ajax was a step towards RIA, and RIA was the step towards more traditional desktop applications (not that they are flawless). Are you saying that we need to recreate the familiar web environment despite how inconveninent it was at the first place? Aren't webapps and desktop apps supposed to meet and converge into just apps? Isn't this what Avalon/XAML is trying to do?

    I totally agree that Ajax apps must accept full crome and must perform sensibly while a user navigates in session history or reloads a page. I believe that your approach can help designing navigation paths more selectively and more sensible from business object and business process point of view. Your library is a one great hammer, I just hope that people won't start seeing nails everywhere ;)
  12. I actually believe the whole RIA idea of recreating desktop applications in the browser is wrong. I believe in super-charged web pages, not desktop apps on the web.

    However, keep in mind that I do believe in fully client-side, advanced AJAX applications that live in the browser, however, I believe that they should continue to maintain the illusion that they are web pages. The reason to do so is for usability and familiarity, not for technological ones. Technologically you can recreate desktop apps in the browser, as HalfBrain did in 1999 (http://www.pcworld.com/news/article/0,aid,13848,00.asp). Notice, though, that no one used it. Avalan and XAML are the wrong approach as well.

    I totally agree that people should avoid turning RSH into a golden hammer. Use it if it makes sense, abandon it if it doesn't. I'm not religious about it. :) I just made it because I need it for my own work, and I do believe that the back button is an important UI tool.

    Also, I do believe that things like Microsoft Office will migrate to the web, but they will feel much different; they will be much more about communication and collaboration than printing pretty documents; see a previous project of mine named Paper Airplane at http://codinginparadise.org/paperairplane for what a truly collaborative word processor could look like.

    Michael, nice debate! :)
  13. One thing I should have mentioned is that the Really Simple History library gives the application writer complete control over what to add into history, so some of Michael's concerns are dealt with. If your application doesn't believe that clicking a sidebar should be in history, then you don't have to call dhtmlHistory.add() on it.
  14. simpler solution?[ Go to top ]

    My Really Simple History library embeds things similar to what Mark is doing, plus some other things to avoid common problems that all the other known history libraries suffer from (see the following blog post for details on what these other libraries suffer from: http://codinginparadise.org/weblog/2005/09/ajax-history-libraries.html). Note that the Backbase framework recently fixed the history issues I identified in the above blog post.

    The Really Simple History library wraps what are essentially browser hacks with a clean API. If you want to directly implement them yourself from Mark's article (even though what he has in there is not enough to truly solve history), you can do so. RSH is under a BSD license, though, so it's very business friendly; I don't know why you would want to do it by hand. It took about a month of full time development to get solid.
  15. simpler solution?[ Go to top ]

    Sorry, that should have been Mike, not Mark. :)
  16. simpler solution?[ Go to top ]

    Brad,
    I actually did use Mike's article to implement my initial solution. I had to make several changes to adapt it to our application and haven't fully incorporated the IE back button IFrame fix. And there was a lot of "hand-coding".

    I'd rather use a library for this and I'm happy to learn you've written one. Can wait to try it out!

    Thanks,
    Sanjiv
  17. simpler solution?[ Go to top ]

    No prob Sanjiv. Thanks for the comments!
  18. oops[ Go to top ]

    Can't wait to try it out! :)
  19. Will Answer Questions[ Go to top ]

    Thanks for posting and discussing the article. I'm the author of the article and framework, so if you have any questions or comments I can answer them here. I will monitor the discussion today.

    Best,
      Brad Neuberg
  20. More Discussion[ Go to top ]

    Hi folks; there is also discussion on the article and the Really Simple History framework going on at the O'Reilly Network at http://www.onjava.com/pub/a/onjava/2005/10/26/ajax-handling-bookmarks-and-back-button.html?page=last#thread
  21. A related article, solves the problem of how to add Ajax to existing Struts app has been published on Java.Net:
    http://today.java.net/pub/a/today/2005/10/27/sprinkle-ajax-magic-into-struts-webapp.html?page=1