简体   繁体   English

AngularJS-$ location html5Mode如何工作?

[英]AngularJS - How does $location html5Mode work?

I'm asking this because a couple of times now, I've tried to play around with the $locationProvider.html5Mode(true) command along with <base href="/"> and ran into a lot of errors calling the scripts/styles/images for my project. 我之所以这样问,是因为有几次,我尝试将$locationProvider.html5Mode(true)命令与<base href="/">并遇到很多调用脚本/的错误。我的项目的样式/图像。 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? 还是我不太了解base href的特定工作方式?

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. 它实际上是一个静态网站,但是我想利用Angular的路由来确保所有页面都可以立即加载。 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. 所以我知道这个文件夹结构不是很好,但是我只会在这个项目中使用Angular进行路由,仅此而已,所以它满足了我的需求。

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. 我将<base href="/">放入头部,放入ng-appng-controller主体,并且在主体内部也放入<div ng-view>

I added in the $locationProvider.html5Mode(true) and tried the app out. 我添加了$locationProvider.html5Mode(true)并尝试了该应用程序。 All of my scripts are then being loaded as http://localhost:8888/script.js which is incorrect. 然后,我所有的脚本都被加载为http://localhost:8888/script.js ,这是不正确的。 The project is located in a folder so that index.html is located in http://localhost:8888/my-project/index.html . 该项目位于一个文件夹中,以便index.html位于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. 因此,例如,应该从http://localhost:8888/my-project/js/angular/app.js加载脚本。

Is there something that I'm not understanding about the base href ? 关于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. 最终,我可能将此应用程序托管在在线某个位置,因此我希望脚本等的URL都与该文件真正相关。 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. 好了,因此在base href标记上方,我将具有CSS样式,该样式将作为css/style.css链接,在body标记的底部,我的脚本将被加载为js/init.jsjs/angular/app.js例如js/angular/app.js This would try to load it as if the js folder is located directly at localhost:8888/js . 这将尝试加载它,就像js文件夹直接位于localhost:8888/js

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. Angular框架是一个单页应用程序(SPA),它可以通过使用“哈希”( # )页面锚点从本质上诱使浏览器运行代码段而不是进行服务器调用,从而在浏览器中运行。 Normally, a URL with a # would jump to a specific anchor point in the page; 通常,带有#的URL会跳到页面中的特定锚点。 in the case of Angular or other similar SPA frameworks, the # is redirected to a code segment instead. 如果是Angular或其他类似的SPA框架,则将#重定向到代码段。

Ideally, you would like to not have to reference this # in your page URLs. 理想情况下,您不必在页面URL中引用此# This is where Html5Mode comes into play. 这就是Html5Mode起作用的地方。 Html5Mode is able to hide the # , by using the HTML5 Push State (aka history API). Html5Mode可以使用HTML5推送状态 (又称为历史记录API) 隐藏 #

When Html5Mode is enabled, the normal links on the page are silently replaced by Angular with event listeners. 启用Html5Mode时,页面上的普通链接将被事件监听器以无提示方式替换为Angular。 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. 当您处理正在运行的应用程序中单击的链接时,这一切都很好,但是如果您从尚未将Angular加载到内存中的外部源导航到该页面,则依赖事件侦听器将无法工作。 To deal with this, you must be loading your pages from a web server which supports URL rewrites . 要解决此问题,您必须从支持URL重写的Web服务器加载页面。 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. 当服务器收到对没有物理页面的URL的请求时,服务器将重写URL以加载基本HTML页面,在该页面中可以加载Angular并进行接管。

When Angular receives a request for a route which has been rewritten in this manner, it must first determine what the intended route was. 当Angular收到对以这种方式重写的路线的请求时,它必须首先确定目标路线是什么。 This is where the Base HTML Tag comes into play. 这是Base HTML标记起作用的地方。 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. Angular使用Base引用来帮助它确定URL的哪一部分在服务器上以及哪一部分是客户端路由。 Essentially, where the # in the URL would be if Html5Mode was not enabled. 本质上,如果未启用Html5Mode,则URL中的#位于。

Unfortunately, Base is an HTML Tag that is used by the browser for more than just Angular. 不幸的是, Base是一个HTML标记,浏览器不仅将其用于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. 通常,如果所有脚本和资源都与Index.html文件的位置有关,则这不是问题。 When Base is omitted, the browser will load scripts from the apparent base path determined by the current URI. 如果省略Base ,则浏览器将从当前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. 通常,除非您在网站的子页面上托管有角度的脚本,并且希望用户希望URL字符串中包含某些特定内容,否则应始终控制服务器的基础,并在客户端上使用Base="/"侧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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