Rectangle 27 352

Hashbang in HTML5 Mode

The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

  • Hashbang in HTML5 Mode

For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

In order to simulate URL rewriting you must actually set html5mode to true and decorate the $sniffer class as follows:

This is the case when you need to use URLs with hashes in your HTML files such as in

<a href="index.html#!/path">link</a>
http://www.example.com/base/index.html#!/base/path

As you can see in pure Hashbang mode all links in the HTML files must begin with the base such as "index.html#!".

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

You should set the base in HTML-file

In this mode you can use links without the # in HTML files

http://www.example.com/base/path

This mode is activated when we actually use HTML5 mode but in an incompatible browser. We can simulate this mode in a compatible browser by decorating the $sniffer service and setting history to false.

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

Set the base in HTML-file:

<html>
  <head>
    <base href="/">
  </head>
</html>

In this case the links can also be written without the hash in the HTML file

<a href="/path">link</a>

Link in Browser:

http://www.example.com/index.html#!/base/path

Thank you for the detailed explanation, @jupiter. I'll look at whether I can skip the bang and keep the hash and trick Angular into not requiring two sets of URLs depending on the mode!

I think I have not properly understood your problem. Why don't you use just URLs without a hash? They will work in browsers supporting the history API and browsers not supporting the history API. AngularJS will put the # version into the location bar when you click on them in browsers not supporting the history API as AngularJS intercepts clicks on links.

I'm working on a framework that should support both modes. App authors should be able to choose one or the other without worrying about whether or not there are hashes in their templates and/or changes in the interpretation of relative paths. I'm hopeful that your trick will help make it true that "all you do is change the mode" (even if the practical solution is "set the mode to html5 and then lie to angular about the browser capabilities").

$provide

@pate -- you need to inject $provide in your config function when you're setting up the decorator.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing
Rectangle 27 351

Hashbang in HTML5 Mode

The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

  • Hashbang in HTML5 Mode

For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

In order to simulate URL rewriting you must actually set html5mode to true and decorate the $sniffer class as follows:

This is the case when you need to use URLs with hashes in your HTML files such as in

<a href="index.html#!/path">link</a>
http://www.example.com/base/index.html#!/base/path

As you can see in pure Hashbang mode all links in the HTML files must begin with the base such as "index.html#!".

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

You should set the base in HTML-file

In this mode you can use links without the # in HTML files

http://www.example.com/base/path

This mode is activated when we actually use HTML5 mode but in an incompatible browser. We can simulate this mode in a compatible browser by decorating the $sniffer service and setting history to false.

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

Set the base in HTML-file:

<html>
  <head>
    <base href="/">
  </head>
</html>

In this case the links can also be written without the hash in the HTML file

<a href="/path">link</a>

Link in Browser:

http://www.example.com/index.html#!/base/path

Thank you for the detailed explanation, @jupiter. I'll look at whether I can skip the bang and keep the hash and trick Angular into not requiring two sets of URLs depending on the mode!

I think I have not properly understood your problem. Why don't you use just URLs without a hash? They will work in browsers supporting the history API and browsers not supporting the history API. AngularJS will put the # version into the location bar when you click on them in browsers not supporting the history API as AngularJS intercepts clicks on links.

I'm working on a framework that should support both modes. App authors should be able to choose one or the other without worrying about whether or not there are hashes in their templates and/or changes in the interpretation of relative paths. I'm hopeful that your trick will help make it true that "all you do is change the mode" (even if the practical solution is "set the mode to html5 and then lie to angular about the browser capabilities").

$provide

@pate -- you need to inject $provide in your config function when you're setting up the decorator.

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing
Rectangle 27 1

By default Angular uses something called hashbang mode, you can turn this off and use HTML5 mode - with this you get nice urls - but it won't work in old browsers. To turn this on, put the line below in the config section of your app - remeber to inject $locationProvider.

$locationProvider.html5Mode(true);

angular routing - Custom angularjs route url - Stack Overflow

angularjs angular-routing
Rectangle 27 0

Hashbang in HTML5 Mode

The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

  • Hashbang in HTML5 Mode

For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

In order to simulate URL rewriting you must actually set html5mode to true and decorate the $sniffer class as follows:

This is the case when you need to use URLs with hashes in your HTML files such as in

<a href="index.html#!/path">link</a>
http://www.example.com/base/index.html#!/base/path

As you can see in pure Hashbang mode all links in the HTML files must begin with the base such as "index.html#!".

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

You should set the base in HTML-file

In this mode you can use links without the # in HTML files

http://www.example.com/base/path

This mode is activated when we actually use HTML5 mode but in an incompatible browser. We can simulate this mode in a compatible browser by decorating the $sniffer service and setting history to false.

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

Set the base in HTML-file:

<html>
  <head>
    <base href="/">
  </head>
</html>

In this case the links can also be written without the hash in the HTML file

<a href="/path">link</a>

Link in Browser:

http://www.example.com/index.html#!/base/path

Thank you for the detailed explanation, @jupiter. I'll look at whether I can skip the bang and keep the hash and trick Angular into not requiring two sets of URLs depending on the mode!

I think I have not properly understood your problem. Why don't you use just URLs without a hash? They will work in browsers supporting the history API and browsers not supporting the history API. AngularJS will put the # version into the location bar when you click on them in browsers not supporting the history API as AngularJS intercepts clicks on links.

I'm working on a framework that should support both modes. App authors should be able to choose one or the other without worrying about whether or not there are hashes in their templates and/or changes in the interpretation of relative paths. I'm hopeful that your trick will help make it true that "all you do is change the mode" (even if the practical solution is "set the mode to html5 and then lie to angular about the browser capabilities").

$provide

@pate -- you need to inject $provide in your config function when you're setting up the decorator.

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing
Rectangle 27 0

Hashbang in HTML5 Mode

The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

  • Hashbang in HTML5 Mode

For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

In order to simulate URL rewriting you must actually set html5mode to true and decorate the $sniffer class as follows:

This is the case when you need to use URLs with hashes in your HTML files such as in

<a href="index.html#!/path">link</a>
http://www.example.com/base/index.html#!/base/path

As you can see in pure Hashbang mode all links in the HTML files must begin with the base such as "index.html#!".

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

You should set the base in HTML-file

In this mode you can use links without the # in HTML files

http://www.example.com/base/path

This mode is activated when we actually use HTML5 mode but in an incompatible browser. We can simulate this mode in a compatible browser by decorating the $sniffer service and setting history to false.

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

Set the base in HTML-file:

<html>
  <head>
    <base href="/">
  </head>
</html>

In this case the links can also be written without the hash in the HTML file

<a href="/path">link</a>

Link in Browser:

http://www.example.com/index.html#!/base/path

Thank you for the detailed explanation, @jupiter. I'll look at whether I can skip the bang and keep the hash and trick Angular into not requiring two sets of URLs depending on the mode!

I think I have not properly understood your problem. Why don't you use just URLs without a hash? They will work in browsers supporting the history API and browsers not supporting the history API. AngularJS will put the # version into the location bar when you click on them in browsers not supporting the history API as AngularJS intercepts clicks on links.

I'm working on a framework that should support both modes. App authors should be able to choose one or the other without worrying about whether or not there are hashes in their templates and/or changes in the interpretation of relative paths. I'm hopeful that your trick will help make it true that "all you do is change the mode" (even if the practical solution is "set the mode to html5 and then lie to angular about the browser capabilities").

$provide

@pate -- you need to inject $provide in your config function when you're setting up the decorator.

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing
Rectangle 27 0

This took me a while to figure out so this is how I got it working - Angular WebAPI ASP Routing without the # for SEO

I needed a certain controller (which was in the home controller) to be ignored for uploading images so I added that rule to RouteConfig

routes.MapRoute(
        name: "Default2",
        url: "Home/{*.}",
        defaults: new { controller = "Home", action = "SaveImage" }
    );
  • In Global.asax add the following - making sure to ignore api and image upload paths let them function as normal otherwise reroute everything else. private const string ROOT_DOCUMENT = "/Index.html"; protected void Application_BeginRequest(Object sender, EventArgs e) { var path = Request.Url.AbsolutePath; var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase); var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase); if (isApi || isImageUpload) return; string url = Request.Url.LocalPath; if (!System.IO.File.Exists(Context.Server.MapPath(url))) Context.RewritePath(ROOT_DOCUMENT); }

Make sure to use $location.url('/XXX') and not window.location ... to redirect

Reference the CSS files with absolute path

and not

<link href="app/content/bootstrapwc.css" rel="stylesheet" />

Final note - doing it this way gave me full control and I did not need to do anything to the web config.

Hope this helps as this took me a while to figure out.

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing
Rectangle 27 0

You need to have to a default route for thoughts

{
  url: '/thoughts',
  config: {
    templateUrl: 'app/article/article.html',
    title: 'article',
  }
}

asp.net mvc - AngularJS MVC 4 routing, html5 hashbang urls - Stack Ove...

asp.net-mvc angularjs
Rectangle 27 0

This took me a while to figure out so this is how I got it working - Angular WebAPI ASP Routing without the # for SEO

I needed a certain controller (which was in the home controller) to be ignored for uploading images so I added that rule to RouteConfig

routes.MapRoute(
        name: "Default2",
        url: "Home/{*.}",
        defaults: new { controller = "Home", action = "SaveImage" }
    );
  • In Global.asax add the following - making sure to ignore api and image upload paths let them function as normal otherwise reroute everything else. private const string ROOT_DOCUMENT = "/Index.html"; protected void Application_BeginRequest(Object sender, EventArgs e) { var path = Request.Url.AbsolutePath; var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase); var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase); if (isApi || isImageUpload) return; string url = Request.Url.LocalPath; if (!System.IO.File.Exists(Context.Server.MapPath(url))) Context.RewritePath(ROOT_DOCUMENT); }

Make sure to use $location.url('/XXX') and not window.location ... to redirect

Reference the CSS files with absolute path

and not

<link href="app/content/bootstrapwc.css" rel="stylesheet" />

Final note - doing it this way gave me full control and I did not need to do anything to the web config.

Hope this helps as this took me a while to figure out.

angularjs - $location / switching between html5 and hashbang mode / li...

angularjs angular-routing