Angular1.0路由的Hashbang和HTML5模式
原文答主jupiter
The documentationis not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:
- Hashbang Mode
- HTML5 Mode
- 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:
$provide.decorator('$sniffer', function($delegate) {
$delegate.history = false;
return $delegate;
});
I will now explain this in more detail:
Hashbang Mode
Configuration:
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(false)
.hashPrefix('!');
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>
In the Browser you must use the following Link: 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#!".
HTML5 Mode
Configuration:
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(true);
You should set the base in HTML-file
<html>
<head>
<base href="/">
</head>
</html>
In this mode you can use links without the # in HTML files
<a href="/path">link</a>
Link in Browser:
http://www.example.com/base/path
Hashbang in HTML5 Mode
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.
Configuration:
$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
使用最后一种, html内用{{linkPrefix}} 等于'/', 结果自动在/后面加上!#并且能回退自如,直接访问地址栏
(function () {
'use strict';
var appConfig = function ($routeProvider, jwtInterceptorProvider, $httpProvider, $locationProvider,$provide) {
$routeProvider.otherwise('/404');
//jwtInterceptorProvider.tokenGetter = function (store) {
// return store.get('jwt');
//可以使用多个decorator
$provide.decorator('$locale', function ($delegate) {
var value = $delegate.DATETIME_FORMATS;
value.SHORTDAY = [
"",
"",
"",
"",
"",
"",
""
];
return $delegate;
});
//装饰sniffer
$provide.decorator('$sniffer', function($delegate) {
$delegate.history = false;
return $delegate;
});
$httpProvider.interceptors.push('jwtInterceptor');
$httpProvider.interceptors.push('TokenInterceptor');
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: true });
$locationProvider.hashPrefix('!');
};
appConfig.$inject = ['$routeProvider', 'jwtInterceptorProvider', '$httpProvider', '$locationProvider','$provide'];
var appRun = function ($rootScope,$window, $location, jwtHelper,$translate, AuthService, $sessionStorage,deviceDetector) {
$rootScope.isMobile="is_mobile";
$rootScope.screenWidth=$window.innerWidth;
if ((deviceDetector.os==="android"||deviceDetector.os==="ios" ||deviceDetector.os==="windows-phone"||deviceDetector.device==="blackberry")&& $rootScope.screenWidth<)
$rootScope.isMobile=true;
else $rootScope.isMobile=false;
// Store user data in $rootScope.account if user is logged in
if ($sessionStorage.jwt && !jwtHelper.isTokenExpired($sessionStorage.jwt)) {
var jwt = $sessionStorage.jwt;
$rootScope.account = jwt && jwtHelper.decodeToken(jwt);
}
$rootScope.$on('$routeChangeStart', function (e, to) {
if (to.data) {
if (to.data.requiresLogin) {
// Stop users from getting to routes that have value requiresLogin set on true
if (!$sessionStorage.jwt || jwtHelper.isTokenExpired($sessionStorage.jwt)) {
e.preventDefault();
$translate("Token Expired.").then(function(value){
$rootScope.tokenExpired=value;
$window.alert($rootScope.tokenExpired);
}
);
$location.path('/');
}
} else {
// Stop users from getting to routes that have value requiresLogin set on false
if ($sessionStorage.jwt && !jwtHelper.isTokenExpired($sessionStorage.jwt)) {
e.preventDefault();
$location.path(AuthService.getLoginRedirectUrl());
}
}
}
});
};
appRun.$inject = ['$rootScope', '$window','$location', 'jwtHelper','$translate', 'AuthService', '$sessionStorage','deviceDetector'];
angular
.module('warrantyProcessApp', [
'ngRoute',
... ...
])
.config(appConfig)
.run(appRun);
})();
例子
不过我得到的路径是http://www.example.com/#!/base/path
访问根目录是http://www.example.com/#!/ ( 后面的/#!/都是访问时自动rewirte 到地址栏的 )
知乎: URL 中的 #! 是什么意思?
http://twitter.com/#!/username
http://17startup.com/#!/index
如果说是地址重写或者是restful风格为什么要用#!这么奇怪的地址呢?
但近年来 hash tag 越来越多地被用于 AJAX 请求获取数据,不同 hash tag 对应的网页内容也有所不同,为了有效地区别这种情况和过去传统的页内锚点标示,让搜索引擎更好地抓取 AJAX 数据,Google 提出的解决方案 (似乎是在 2009 年) 是用 #! (被称为 hashbang ) 来进行区分,他们将带有 #! 的 URL 称为 pretty AJAX URL (http://code.google.com/web/ajaxcrawling/docs/getting-started.html F.Y.I.)。当网页爬虫遇到这样的 URL 就会将带不同 hash tag 的 URL 当做不同内容来进行抓取,从而获得更全的信息。
Google 的这一方案如果被其他搜索引擎广泛采纳 (据说 Bing 和 Yahoo! 可能都已支持),无疑将成为一个事实标准,如果富 AJAX 网站想进行进一步的 SEO,也就会越来越多地支持这样的格式。
Twitter 和 Google 前两年曾有过不错的合作,所以支持得比较早吧。
Google抓取#的机制
默认情况下,Google的网络蜘蛛忽视URL的#部分。但是,Google还规定,如果你希望Ajax生成的内容被浏览引擎读取,那么URL中可以使用"#!",Google会自动将其后面的内容转成查询字符串_escaped_fragment_的值。比如,Google发现新版twitter的URL如下:http://twitter.com/#!/username就会自动抓取另一个URL:http://twitter.com/?_escaped_fragment_=/username通过这种机制,Google就可以索引动态的Ajax内容。
文章全文请参考:http://www.ruanyifeng.com/blog/2011/03/url_hash.html
传统jQuery方法:
利用 HTML5 history session management 作为历史记录:
This way you don't have to use hashes in newer browsers and that way the user won't notice a thing.
function route(path) {
$.get(path, function(data) {
//parse data
});
}
if (typeof history.pushState !== 'undefined')
{
$(window).bind('popstate', function(e)
{
route(window.location.pathname);
});
$('a').click(function(event) {
event.preventDefault();
history.pushState({},'',this.href);
});
} else {
$(window).bind('hashchange', function(e)
{
route(window.location.hash);
});
$('a').click(function(event) {
event.preventDefault();
$(this).attr('href', '/#'+$(this).attr('href'));
});
}
延伸阅读:
angular 路由去除#号
http://www.cnblogs.com/breakdown/p/3785773.html
Angular1.0路由的Hashbang和HTML5模式的更多相关文章
- ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系
ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...
- Django2.0路由层-URLconf
目录 DJango2.0路由层-URLconf 概述 urlpatterns 实例 path转换器 自定义path转换器 使用正则表达式 命名组(有名分组) URLconf匹配请求URL中的哪些部分 ...
- ThinkPHP5.0框架开发--第4章 TP5.0路由
ThinkPHP5.0框架开发--第4章 TP5.0路由 第4章 TP5.0 路由 ================================================== 上次复习 1. ...
- vue 2.0 路由切换以及组件缓存源代码重点难点分析
摘要 关于vue 2.0源代码分析,已经有不少文档分析功能代码段比如watcher,history,vnode等,但没有一个是分析重点难点的,没有一个是分析大命题的,比如执行router.push之后 ...
- $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传
1 虚拟环境:解决问题同一台机器上可以运行不同版本的django, 1 用pychanrm创建--->files-->newproject--->选择虚拟环境 2 setting ...
- vue2.0路由
现在用vue-cli搭建的环境里面vue-router是下载好的 vue2.0路由方式和以前也有些不同 没了了map和start方法 目录结构如上图 这里有三个文件,app.vue显示,main.js ...
- vue2.0路由写法、传参和嵌套
前置知识请戳这里 vue-routerCDN地址:https://unpkg.com/vue-router@3.0.1/dist/vue-router.js vue-router下载地址:https: ...
- Django day05 虚拟环境 django 2.0和django 1.0 路由层区别
一:虚拟环境 创建虚拟环境一般有三种方式: 1) File--->New Project--> 出现如下图,点击Project Interpreter:New Virtualenv e ...
- OLE DB访问接口“MICROSOFT.JET.OLEDB.4.0”配置为在单线程单位模式下运行,所以该访问接口无法用于分布式
OLE DB访问接口"MICROSOFT.JET.OLEDB.4.0"配置为在单线程单位模式下运行,所以该访问接口无法用于分布式 数据库操作excel时遇到的以上问题的解决方法 解 ...
随机推荐
- android中提示&对话框----Notification
Notification(状态栏通知) 一.Notification用于状态栏显示通知的控件,在不同的设备上面Notification是不一样的 二.Notification的基本布局 元素组成: I ...
- NWU现场赛——解题报告
负二进制转换 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Problem Desc ...
- 使用putty通过证书登录Linux
refer to: https://www.aliyun.com/jiaocheng/200196.html
- bzoj1455&&luogu2713罗马游戏
罗马游戏 题目描述 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻. ...
- Arduino可穿戴教程Linux平台下安装Arduino IDE
Arduino可穿戴教程Linux平台下安装Arduino IDE Linux平台下安装Arduino IDE Linux平台下的安装方式和Windows下的zip形式安装是类似的,只是Linux下的 ...
- concurrencyProgrammingGuide 1
thread用来表述执行代码的独立path.os x的线程执行基于POSIX 线程API. process用来表述一个运行操作,可以包含多个线程. task用来描述工作的抽象概念. Concurren ...
- [置顶]
个人微信号发送zabbix告警信息
之前使用邮件和短信发送zabbix告警信息,但告警信息无法实时查看或者无法发送,故障无法及时通知运维人员. 后来使用第三方微信接口发送信息,愉快地用了一年多,突然收费了. zabbix告警一直是我的痛 ...
- PHP页面跳转几种实现方法
转载自冠威博客 [ http://www.guanwei.org/ ]本文链接地址:http://www.guanwei.org/post/PHPnotes/04/php-redirect-metho ...
- nodejs session 设计
会话管理 { //保存会话 _data : {}, /** 会话基本操作 ***/ //查找会话 getSession : function(id){}, //创建会话 createSession : ...
- 【京东个人中心】——Nodejs/Ajax/HTML5/Mysql爬坑之静态页面
一.引言 接着上一篇,京东个人中心的所有功能数据分析完成之后,现在需要把静态页面完成,实现过程中要用到的技术有:Bootstrap.html5表单新特性等.除此之外,还要利用Node.js的Expre ...