AngularJS - $ location html5Mode如何工作?

时间:2015-07-07 01:54:20

标签: javascript angularjs

我问这个是因为现在有几次,我试图用$locationProvider.html5Mode(true)命令和<base href="/">一起玩,并且遇到很多错误调用脚本/样式/我的项目的图像。我想肯定有一些我做错了,但你应该遵循某种文件夹结构,这样你就不会遇到这些错误吗?或者有一种特定的方式使base href起作用,我不太了解吗?

最近,我想我会在一个非常非常小的应用程序上尝试它。它实际上是一个静态网站,但我想利用Angular的路由来确保所有页面都能立即加载。所以我的结构将是这样的:

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

所以我知道这个文件夹结构不是很好,但我只会在这个项目中使用Angular进行路由,仅此而已,它符合我的需求。

我放入头部<base href="/">,放入身体ng-appng-controller,身体内部也放置<div ng-view>

我添加了$locationProvider.html5Mode(true)并尝试了该应用。然后我的所有脚本都被加载为http://localhost:8888/script.js,这是不正确的。该项目位于一个文件夹中,index.html位于http://localhost:8888/my-project/index.html。因此,它应该从http://localhost:8888/my-project/js/angular/app.js加载脚本,例如。

是否有一些我不了解base href的内容?最终我可能会在网上某个地方托管这个应用程序,所以我希望URL到脚本等都真正与文件相关。有人有什么想法吗?

好吧,在base href标记之上,我会将我的CSS样式链接为css/style.css,并在body标记的底部我将我的脚本加载为{例如{1}}或js/init.js。这会尝试加载它,就好像js/angular/app.js文件夹直接位于js

1 个答案:

答案 0 :(得分:10)

Angular框架是一个单页面应用程序(SPA),能够在浏览器中运行,基本上欺骗浏览器运行代码片段而不是通过使用&来进行服务器调用#34;散列&#34; (#)页面锚点。通常,带有#的URL会跳转到页面中的特定锚点;对于Angular或其他类似的SPA框架,#会被重定向到代码段。

理想情况下,您希望不必在网页网址中引用此#。这就是Html5Mode发挥作用的地方。通过使用HTML5 Push State(又名历史API),Html5Mode能够隐藏 #

启用Html5Mode后,页面上的普通链接会被Angular静态替换为事件侦听器。触发这些事件后,当前页面将被推入浏览器历史记录,并加载新页面。这给人一种幻觉,即您正在导航到新页面,甚至允许后退按钮运行。

当您处理从正在运行的应用程序中单击的链接时,这一切都很好,但如果您从外部源导航到该页面,依赖于事件侦听器是不行的,其中Angular不是。尚未加载到内存中。要解决此问题,您必须从支持URL rewrites的Web服务器加载页面。当服务器收到没有物理页面的URL请求时,它会重写URL以加载基本HTML页面,Angular可以加载并接管。

当Angular收到以这种方式重写的路由请求时,必须首先确定预期路由是什么。这是Base HTML Tag发挥作用的地方。 Angular使用Base引用来帮助它确定URL的哪个部分在服务器上,哪个部分是客户端路由。基本上,如果未启用Html5Mode,则URL中的#将会出现。

不幸的是,Base是一个HTML标记,浏览器使用的不只是Angular。浏览器还使用此标记来确定使用相对路径加载脚本和资源的正确位置,而不管位置栏中的路径如何。通常,如果所有脚本和资源都与Index.html文件的位置相关,则这不是问题。省略Base时,浏览器将从当前URI确定的 explicit 基本路径加载脚本。但是,一旦提供,浏览器将使用您提供的任何值。

一般情况下,除非您在网站的子页面上托管角度,并且您希望用户期望URL字符串中有特定内容,否则您应始终控制服务器上的基础,并使用Base="/"在客户端。