logo

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:

image

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:

image

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:

image

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:

image

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.

Comments

  1. nice tip, i have a use for that now

    • avatar
    • Andrew Tetlaw
    • Mon 28 Feb 2011 05:54 AM

    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

      • avatar
      • Jake Howlett
      • Mon 28 Feb 2011 08:52 AM

      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

      Hide the rest of this thread

      1. Nah, it could have been # and anything accept ? really.

        The fragment identifier was required because it's the only way to change the URL without reloading the page.

        ! is used because it's an acceptable URL character that wasn't a ?. Google converts everything after the ! into a query string so you can't have 2 ? characters. Also ! is not much used in URLs so it was safe to choose.

        Thus #!

        There's no other reason for this URL pattern to exist accept that Google suggested it.

          • avatar
          • Jake Howlett
          • Wed 2 Mar 2011 02:53 AM

          I think you've missed what I was getting at. It's not the *technical* reason behind the choice of "#!" that I was wondering about. I was just wondering if the choice had anything to do with Perl or Unix, which I'd assume it does.

          1. Nope, pure coincidence.

              • avatar
              • Jake Howlett
              • Wed 2 Mar 2011 04:01 AM

              How can you say that with such conviction?

              1. Because that blog post says as much: "Instead of a URL like http://example.com/page?query#state we would like to propose adding a token to make it possible to recognize these URLs: http://example.com/page?query#[FRAGMENTTOKEN]state . Based on a review of current URLs on the web, we propose using "!" (an exclamation point) as the token for this."

  2. "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

      • avatar
      • Jake Howlett
      • Mon 28 Feb 2011 08:27 AM

      if they don't like it they can come find me at twitter.com ;-)

      • avatar
      • Sean Peters
      • Mon 28 Feb 2011 09:19 AM

      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.

      Show the rest of this thread

  3. 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. :-)

      • avatar
      • Jake Howlett
      • Mon 28 Feb 2011 12:23 PM

      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.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Mon 28 Feb 2011

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

Elsewhere

Here are the external links posted on the same day.

More links are available in the archive »

More Content