Using AJAX Hashbangs With Domino Login Redirects
What a title. Never thought I'd say "hash bang". In fact last week I said it out loud. To a person. Little surprise that they just stared back and said "You what?"
The developer I was talking to has built a Domino-powered website that uses Ajax to load all the content. Putting aside the whys and wherefores for now, the big question I had was "How do you bookmark a page or send out emails with links to content?". Their answer: "Errm, we can't".
They asked if I knew a way round not being able to "deep link" and that's when I said "hashbangs".
What Is A Hashbang?
Here's a URL to a page on Twitter that shows the nonsense I spout my tweets:
http://twitter.com/#!/jakehowlett
I've highlighted the Hashbang part of it. It's the number/pound/hash sign (#) followed by an exclamation/bang sign (!).
As I'm sure you know, the # symbol in a URL signifies the start of the anchor/hash region. It's the way you tell the browser which part of the page to jump to once it's loaded.
The important point about URL hashes is that they do not get sent to the server. The server doesn't care what part of the page you want to jump to once it's been loaded back from the server.
If you loaded the above Twitter URL and looked at the HTTP traffic you'd see the browser requested a GET for "http://twitter.com/" and nothing else. The server returns the content at the root of the site. Then, in the page's "onload" event, it uses JavaScript to examine the browser's URL to see what's in the location.hash property. If it starts with an exclamation mark then it knows to use Ajax to request more from the server.
Why use an exclamation mark? I'm not sure, but I guess one reason is that it's not a legal character to use in an ID in the DOM, so it's not a legal anchor. The other reason is probably embedded in Unix/Perl geekery.
So, that's how Twitter (and a few other sites) works. When you click on other Twitter-based URLs inside Twitter it just changes the URLs hash at the same time as it sends off an Ajax request. The whole page does not reload each time.
Whether hashbangs are evil is a matter for debate and not something I want to get in to right now. What I want to talk about is how you can use them with Domino. In particular Domino sites that require the user logs in.
Using HashBangs With Authenticated Domino Websites
Hashbangs work with Domino. There's no reason they shouldn't. It doesn't matter what server you're using really, as it's all about the JavaScript.
The problems start when your Domino site requires you login. If you click a URL that has a hashbang in it and Domino asks you to login, once you've logged in the hashbang will disappear from the URL.
This happens because the Domino login form uses a hidden field called RedirectTo to store the URL to which a user is returned once authenticated and that field doesn't have the hashbang in it.
Here's the standard "custom" login form from domcfg.nsf:
Notice the RedirectTo field is "type=hidden". Remove that HTML tag so the field shows and you'll see something like this when accessing a Hashbang site that requires authentication:
See how the hashbang is missing!! You get redirected to the URL minus the #! part.
It's because the server doesn't know about the hashbang part of the URL because the browsers doesn't send that part along with the GET request.
As a workaround you can add some JavaScript code immediately after the RedirectTo field, like so:
This code adds the hashbang to the current value of the RedirectTo field. The server then returns the user to the right URL once logged in.
You might be thinking "But, this won't work without JavaScript!". No, it won't. But then neither will the whole Hashbang approach or the whole site for that matter, so it's doesn't really matter in this case.
Notice we didn't put this code in the page's onload event. Onload doesn't fire until all the images are loaded. If, for any reason, that takes longer than it takes the user to enter their credentials (maybe their browser remembers them and they just press enter) then the trick won't work. By putting the code inline with the HTML we "guarantee" it gets applied in time.
Here's what we now see:
Hey presto! Problem solved. Once they've logged in and arrived at your database (hashbang intact) you use the page's onload/domReady event to examine the URL and use Ajax to fetch the right bits.
nice tip, i have a use for that now
Reply
The reason it's a #! is only because of one thing: Google. When site operators realised that their (idiotic) use of Ajax for all page content meant that Google couldn't index their site (the other side of the deep linking problem), Google threw them a bone.
Google said that if they use #! in their URLs to control page content Google would convert the URL into a special query string and then (if they made content available at the URL with the query string) index their content.
http://googlewebmastercentral.blogspot.com/2009/10/proposal-for-making-ajax-crawlable.html
Reply
Lucky for me it's not an indexed site I'm having to work on.
Even though Google came up with the #! there still has to be a "reason" for this combination and why the person inside Google opted for it. My guess is still its roots in unix as the Shebang
Reply
Show the rest of this thread
"You might be thinking 'But, this won't work without JavaScript!'. No, it won't. But then neither will the whole Hashbang approach or the whole site for that matter, so it's doesn't really matter in this case."
Your callousness towards time travelers surfing the web on a copy of Netscape 1.0 is deplorable. :P
Reply
if they don't like it they can come find me at twitter.com ;-)
Reply
This may be getting too much into the question of whether hashbangs are evil, but... sites that don't work without Javascript are bad (ok, yeah, I'm saying hashbangs are evil). I pretty routinely surf with JS disabled via NoScript, and on hashbang style sites, that means I literally get no content at all. So much for graceful degradation. If I'm really keen to see the site, then I'm forced to fiddle around with my NoScript settings to figure out what's going on, but more often, I just blow the site off altogether.
And NoScript weirdos like me aren't your only problem - there are plenty of mobile devices with dodgy JS implementations as well.
I guess I don't really have any answer to this problem, though.
Reply
Show the rest of this thread
I guess I could point out that ajax can work with authentication - it's the specific use of the #! that has issues. One could also redesign the way parameters are passed into an ajax request ,eg not via url but rather as request headers via a post or in cookies.
Timely topic though, as usual. I moved some stuff to an authentication required model this morning and started having other issues with my ajax and authentication. You're always at least 5 hours ahead of me, Jake. :-)
Reply
Cookies and headers might work but the requirement was to make bookmarking and link-emailing work. They needed an explicit URL to get them directly to inner content (which then stayed in place if the user hit F5).
As with everything there's always lots of solutions. Hashbangs seemed the perfect fit in this case.
Reply