简体   繁体   中英

How do I configure angular to use base routes without trailing slashes?

Desired behavior

I have a search page that lives at this URL:

http://example.com/search

The desired behavior is that the provided query parameters get passed to the page, and get updated as the user types a different query.

Eg,

http://example.com/search?q=foo

results in the search box containing "foo" on page load. If the user types "delicious pancakes" into the search box, the location bar's URL will update automatically to this:

http://example.com/search?q=delicious+pancakes

This part is working fine; I'm using $watch to monitor the value of the query and then update the location bar via $location.search('q', newValue) .

But I'd like to use HTML5 mode (I am using $locationProvider.html5Mode(true) ), and I need the hashbang fallback to work for IE9 users.

I would like the hashbang fallback to look like this:

http://example.com/search#?q=delicious+pancakes

The Problem

If I don't set the <base> element, the $location service treats everything after the domain as the path, so it actually falls back to this in IE9:

http://example.com/#search?q=delicious+pancakes

This results in the browser redirecting to the home page (ie, it takes me away from the search page completely!)

So the best practice seems to be to use the <base> tag; so I set it to

<base href="http://example.com/search/"></base>

(Note the trailing slash; I understand this is required by both Angular and by the HTML spec.)

However, this means I must use the following URL:

http://example.com/search/?q=delicious+pancakes

(with the IE9 fallback being http://example.com/search/#?q=delicious+pancakes )

This works, but I don't want to require users to type that slash after "search" and before the question mark. Currently if I try to access the page via http://example.com/search?q=foo , I receive this error in the console:

TypeError: whole is undefined

This error is apparently caused because the $location service's $$rewrite function not returning anything. For reference, I'll copy the source from angular.js:

this.$$rewrite = function(url) {
    var appUrl, prevAppUrl;

    if ( (appUrl = beginsWith(appBase, url)) !== undefined ) {
      prevAppUrl = appUrl;
      if ( (appUrl = beginsWith(basePrefix, appUrl)) !== undefined ) {
        return appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
      } else {
        return appBase + prevAppUrl;
      }
    } else if ( (appUrl = beginsWith(appBaseNoFile, url)) !== undefined ) {
      return appBaseNoFile + appUrl;
    } else if (appBaseNoFile == url + '/') {
      return appBaseNoFile;
}

Is there any way I can achieve the desired behavior without the slash after "search", and still have IE9 support?

Use a conditional statement to exclude IE9 from HTML5mode:

if(!!$window.innerWidth && !$window.matchMedia)
  {
  $locationProvider.html5Mode({enabled: false, requireBase: false});
  $locationProvider.hashPrefix("search");
  }
else
  $locationProvider.html5Mode({enabled: true, requireBase: false});

References

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM