- Mike Davies: Breaking the Web with hash-bangs
- Tim Bray: Broken Links
- James Aylett: Wisdom comes from deliberate reflection
There’s been some great discussion of this issue so far, but a few things have been missing (or in some cases mentioned in passing but not strongly stressed) from the various pieces of analysis I’ve read. Here’s what I think really matters about this:
- It is important to distinguish that not all URIs (“Uniform Resource Identifiers”) are URLs (“Uniform Resource Locators”). A URL is a special kind of URI that ‘provide[s] a means of locating the resource by describing its primary access mechanism (e.g., its network “location”).' I would argue that the real problem with a #! is that the URI now contains information that is semantically relevant to the server, after the fragment separator. As a result, these URIs no longer qualify as URLs because the routing information contained within can no longer be used to find the resource in question. The fragment identifier is supposed to be ignored until you get to the client: "the identifying information within the fragment itself is dereferenced solely by the user agent, regardless of the URI scheme." The issue stems from the reality that just about everybody who deals with URIs expects them to also be URLs, and these are not. This is particularly problematic for keeping track of resources on the internet. http://www.example.com/about.html#contact and http://www.example.com/about.html#team are the same resource. http://twitter.com/#!/fields and http://twitter.com/#!/anythingelse are not, but unless you ignore the #!, they are.
Unfortunately, there is zero consistency in how these urls are being treated on the server side. The only sane response I can see to this is to not parse #! (or /#/, which suffers from the same problems) as a fragment separator. This is clearly in violation of the spec, but so is using anything after the fragment specifier as location information for the resource. (For the rubyists among you, I forked my own version of the addressable gem to do this, though it won’t be incorporated into the main branch because it doesn’t follow the URI spec.)