AngularJS Hash Bang Urls and Query Parameter ordering #6172
Description
According to AngularJS documentation, it states that a hash bang URL is in this format:
http://foo.com/#!/bar?baz=23
This indicates that the hash fragment is between the path and the query parameters of the URL. It's DOMAIN - HASH FRAGMENT - QUERY PARAMETER
However on Google AJAX Crawling Specification, when it converts a hash bang URL into the _escaped_fragment_
format for the purposes of indexing and then converts it back for search results, it instead places the hash fragment after the query parameter. (See the Search Results section)
http://foo.com/?baz=23#!/bar
This indicates DOMAIN - QUERY PARAMETER - HASH FRAGMENT.
It seems that both are a valid URL structure (try it on a browser with any non SPA application). However if you are using this URL format on any AngularJS site, the site correctly ascertains the path, however it "forgets" the query parameters.
So if you go to http://docs.angularjs.org?key=value#!/guide, it turns into http://docs.angularjs.org/guide. As you can see it forgets the query parameters. If I'm using the Google AJAX specification, then this would result in search results having URLs that don't work properly as their query parameters gets dropped.
I did some testing with both urls which has illuminated the problem:
Case 1: Using DOMAIN - HASH - QUERY PARAMETER (AngularJS format) (http://example.com/#!/path?key=value), the query parameters never gets received by the server, but it is remembered on the client side. It's also available in $location.search()
.
Case 2: Using DOMAIN - QUERY PARAMETER - HASH (Google's format) (http://example.com/?key=value#!/path), the query parameter gets received by the server (as it is not after the #), but it is forgotten on the client side. It's also not available in $location.search()
.
Perhaps a solution can be made for case 2. So that when there is query parameter and then hash fragment, AngularJS can correctly remember the query parameter and shift it to the end of the URL (if converting to HTML5 urls) and also make it accessible with $location.search()
. Case 1 cannot be solved due to the URL standards as everything after the # is not sent to the server.