views:

6889

answers:

8

I'm writing an AJAX app, but as the user moves through the app, I'd like the URL in the address bar to update despite the lack of page reloads. Basically, I'd like for them to be able to bookmark at any point and thereby return to the current state.

How are people handling maintaining RESTfulness in AJAX apps? Thanks in advance.

+2  A: 

Basically your links contain anchors:

  1. page.html#Tab1
  2. page.html#Tab2
  3. page.html#Tab3

And when the page loads you check document.location.href and substr the ID off the end to get the state. At least that's how I've been doing it. :(

Hopefully there's a better way.

Kevin
+5  A: 

This is similar to what Kevin said. You can have your client state as some javascript object, and when you want to save the state, you serialize the object (using JSON and base64 encoding). You can then set the fragment of the href to this string.

var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;

document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history

The first way will treat the new state as a new location (so the back button will take them to the previous location). The latter does not.

Edward Luong
Is there a way to add an entry to the bookmark history without refreshing the page? Setting the location (as in your first example) will cause a refresh, won't it?
Drew Noakes
+4  A: 

Looks like you're right. That's the only approach.

This seems like a good detailed explanation of your advice: http://ajaxpatterns.org/Unique_URLs

Thank you for your help.

jasonjwwilliams
+18  A: 

The way to do this is to manipulate location.hash when AJAX updates result in a state change that you'd like to have a discreet URL. For example, this page's URL is:

http://stackoverflow.com/questions/1457/modify-address-bar-url-in-ajax-app-to-match-current-state

If a client side function executed this code:

// AJAX code to display the "foo" state goes here.

location.hash = 'foo';

Then, the URL displayed in the browser would be updated to:

http://stackoverflow.com/questions/1457/modify-address-bar-url-in-ajax-app-to-match-current-state#foo

This allows users to bookmark the "foo" state of the page, and use the browser history to navigate between states.

With this mechanism in place, you'll then just need to parse out the hash portion of the URL on the server side and display the appropriate initial state.

Dave Ward
+2  A: 

SWFAddress works in Flash & Javascript projects and lets you create bookmarkable URLs (using the hash method mentioned above) as well as giving you back-button support.

http://www.asual.com/swfaddress/

+2  A: 

The window.location.hash method is the preferred way of doing things. For an explanation of how to do it, Ajax Patterns - Unique URLs.

YUI has an implementation of this pattern as a module, which includes IE specific work arounds for getting the back button working along with re-writing the address using the hash. YUI Browser History Manager.

Other frameworks have similar implementations as well. The important point is if you want the history to work along with the re-writing the address, the different browsers need different ways of handling it. (This is detailed in the first link article.)

IE needs an iframe based hack, where Firefox will produce double history using the same method.

A: 

Is there any other way to do this in prototype?

Official Movie Trailer
A: 

Check if user is 'in' the page, when you click on the url bar, javascript says you are out of page. If you change the url bar and press 'ENTER' with the symbol '#' within it then you go into the page again, without click on the page manually with mouse cursor, then a keyboad event command (document.onkeypress) from javascript will be able to check if it's enter and active the javascript for redirection. You can check if user is IN the page with window.onfocus and check if he's out with window.onblur.

Yeah, it's possible.

;)

Marcelo
This is the way I saw elegant to change the page when the user edit url bar with the # symbol.
Marcelo