AngularJS - $location html5Mode 如何工作? [英] AngularJS - How does $location html5Mode work?

查看:25
本文介绍了AngularJS - $location html5Mode 如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之所以这么问是因为有几次,我尝试使用 $locationProvider.html5Mode(true) 命令和 <base href="/"> 并在为我的项目调用脚本/样式/图像时遇到了很多错误.我想一定是我做错了什么,但是您是否应该遵循特定的文件夹结构,以免遇到这些错误?或者有没有我不太理解的 base href 工作的特定方式?

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

我的项目css图片js有角的应用程序.jsapp.routes.js主控件.js意见主页.html关于.html联系方式.html索引.html

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

我把<base href="/">放到head里,把ng-appng-controller放到body里, 并且在 body 里面也放一个

.

我添加了 $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 标签 例如,我会将我的脚本加载为 js/init.jsjs/angular/app.js.这将尝试加载它,就像 js 文件夹直接位于 localhost:8888/js 一样.

解决方案

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

理想情况下,您不希望在您的页面 URL 中引用此 #.这就是 Html5Mode 发挥作用的地方.Html5Mode 能够隐藏#,通过使用HTML5 推送状态(又名历史 API).

启用 Html5Mode 后,页面上的正常链接会被带有事件侦听器的 Angular 静默替换.当这些事件被触发时,当前页面被推送到浏览器历史记录中,并加载新页面.这给人一种您正在导航到一个新页面的错觉,甚至可以操作后退按钮.

当您处理从正在运行的应用程序中单击的链接时,这一切都很好,但是如果您从外部源导航到页面,则依赖事件侦听器将无法工作,其中 Angular 未加载到内存中然而.要解决这个问题,您必须从支持 URL 重写.当服务器收到对没有物理页面的 URL 的请求时,它会重写 URL 以加载基本 HTML 页面,Angular 可以在其中加载和接管.

当 Angular 收到对以这种方式重写的路由的请求时,它必须首先确定预期的路由是什么.这就是 Base HTML 标签 发挥作用的地方.Angular 使用 Base 引用来帮助它确定 URL 的哪一部分在服务器上,哪一部分是客户端路由.本质上,如果未启用 Html5Mode,URL 中的 # 将在哪里.

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

通常,除非您在站点的子页面上托管 angular 并且您希望您的用户期望 URL 字符串中的特定内容,否则您应该始终控制服务器上的基础,并使用 Base="/" 在客户端.

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. 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.

解决方案

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 comes 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 comes 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.

这篇关于AngularJS - $location html5Mode 如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆