最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS - How does $location html5Mode work? - Stack Overflow

programmeradmin0浏览0评论

I'm asking this because a couple of times now, I've tried to play around with the $locationProvider.html5Mode(true) mand along with <base href="/"> and ran into a lot of errors calling the scripts/styles/images for my project. I guess there must be something I am doing wrong, but is there a certain folder structure you should follow so you don't run into these errors? Or is there a specific way that the base href works that I'm not quite understanding?

Recently, I thought I'd try it on a very, very small app. It's effectively a static website, but I want to take advantage of Angular's routing to make sure all of the pages can load instantly. So my structure would be something like this:

my-project
    css
    images
    js
        angular
            app.js
            app.routes.js
            mainCtrl.js
    views
        home.html
        about.html
        contact.html
    index.html

So I know that this folder structure isn't great, but I'll only be using Angular in this project for routing, nothing more, so it fits my needs.

I put into the head <base href="/">, put in body ng-app and ng-controller, and inside the body put a <div ng-view> somewhere too.

I added in the $locationProvider.html5Mode(true) and tried the app out. All of my scripts are then being loaded as http://localhost:8888/script.js which is incorrect. The project is located in a folder so that index.html is located in http://localhost:8888/my-project/index.html. So, it should be loading the scripts from http://localhost:8888/my-project/js/angular/app.js for example.

Is there something that I'm not understanding about the base href? Eventually I may host this app somewhere online, so I want the URLs to scripts etc to all be relevant to the file really. Anyone have any ideas?

Alright, so above the base href tag I would have my CSS styles which would be linked as css/style.css and at the bottom of my body tag I would have my scripts loaded as js/init.js or js/angular/app.js for example. This would try to load it as if the js folder is located directly at localhost:8888/js.

I'm asking this because a couple of times now, I've tried to play around with the $locationProvider.html5Mode(true) mand along with <base href="/"> and ran into a lot of errors calling the scripts/styles/images for my project. I guess there must be something I am doing wrong, but is there a certain folder structure you should follow so you don't run into these errors? Or is there a specific way that the base href works that I'm not quite understanding?

Recently, I thought I'd try it on a very, very small app. It's effectively a static website, but I want to take advantage of Angular's routing to make sure all of the pages can load instantly. So my structure would be something like this:

my-project
    css
    images
    js
        angular
            app.js
            app.routes.js
            mainCtrl.js
    views
        home.html
        about.html
        contact.html
    index.html

So I know that this folder structure isn't great, but I'll only be using Angular in this project for routing, nothing more, so it fits my needs.

I put into the head <base href="/">, put in body ng-app and ng-controller, and inside the body put a <div ng-view> somewhere too.

I added in the $locationProvider.html5Mode(true) and tried the app out. All of my scripts are then being loaded as http://localhost:8888/script.js which is incorrect. The project is located in a folder so that index.html is located in http://localhost:8888/my-project/index.html. So, it should be loading the scripts from http://localhost:8888/my-project/js/angular/app.js for example.

Is there something that I'm not understanding about the base href? Eventually I may host this app somewhere online, so I want the URLs to scripts etc to all be relevant to the file really. Anyone have any ideas?

Alright, so above the base href tag I would have my CSS styles which would be linked as css/style.css and at the bottom of my body tag I would have my scripts loaded as js/init.js or js/angular/app.js for example. This would try to load it as if the js folder is located directly at localhost:8888/js.

Share Improve this question edited Jul 7, 2015 at 2:46 germainelol asked Jul 7, 2015 at 1:54 germainelolgermainelol 3,35115 gold badges48 silver badges83 bronze badges 9
  • Sounds like you need <base href="/my-project/"> – Phil Commented Jul 7, 2015 at 2:03
  • 1 base href is not just an angular call but also tells all your relative links where to start from. Where your js files are loaded from shouldn't have anything to do with your angular routing though. How are you loading them and where are you putting the base href? – Jan Commented Jul 7, 2015 at 2:03
  • Can you show an example of your index.html file, in particular the <script> tags – Phil Commented Jul 7, 2015 at 2:08
  • I updated my answer to show you @Phil. I understand that using that base href could work, but I thought that it should be making all files relative to this index file? Or is that not exactly how it will work? For example, if I was to put this app onto a server for the world to see, I would then have to change the `href="/my-project/" again. – germainelol Commented Jul 7, 2015 at 2:46
  • @germainelol yup. The <base> tag sets the root path / URI to base all relative URIs from. If that path changes based on where it's deployed, you need to change it – Phil Commented Jul 7, 2015 at 2:56
 |  Show 4 more ments

1 Answer 1

Reset to default 10

The Angular framework is a Single Page Application (SPA) that is able to run in a browser by essentially tricking the browser into running code snippets rather than make server calls, by making use of the "hash" (#) page anchor. Normally, a URL with a # would jump to a specific anchor point in the page; in the case of Angular or other similar SPA frameworks, the # is redirected to a code segment instead.

Ideally, you would like to not have to reference this # in your page URLs. This is where Html5Mode es into play. Html5Mode is able to hide the #, by using the HTML5 Push State (aka history API).

When Html5Mode is enabled, the normal links on the page are silently replaced by Angular with event listeners. When these events are triggered, the current page is pushed into the browser history, and the new page is loaded. This gives the illusion that you are navigating to a new page, and even allows for the back button to operate.

This is all fine when you are dealing with links which are clicked from within the running application, but relying on event listeners can't work if you navigate to the page from an external source, where Angular isn't loaded into memory yet. To deal with this, you must be loading your pages from a web server which supports URL rewrites. When the server receives a request for a URL that there isn't a physical page for, it rewrites the URL to load the base HTML page, where Angular can be loaded and take over.

When Angular receives a request for a route which has been rewritten in this manner, it must first determine what the intended route was. This is where the Base HTML Tag es into play. Angular uses the Base reference to help it to determine which part of the URL is on the server, and which part is a client route. Essentially, where the # in the URL would be if Html5Mode was not enabled.

Unfortunately, Base is an HTML Tag that is used by the browser for more than just Angular. The browser also uses this tag to determine the correct location to load scripts and resources using relative paths from, regardless of the path in the location bar. In general, this isn't a problem if all of the scripts and resources are relative to the location of the Index.html file. When Base is omitted, the browser will load scripts from the apparent base path determined by the current URI. However, once you provide it, the browser will use whatever value you have supplied.

In general, unless you are hosting angular on a sub-page of your site and you want your users to expect something specific in the URL string, you should always control the base on your server, and use Base="/" on the client side.

发布评论

评论列表(0)

  1. 暂无评论