Angular2+URL中的 # 引发的思考
1.先分析 # 的作用
1.1. # 的涵义
#代表网页中的位置。其右面的字符就是该位置的标识符。比如,http://www.example.com/index.html#print就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。
#是指导浏览器动作的,对服务器完全无效。所以HTTP请求不会包含#及右侧内容
1.2.HTTP请求不包括#
#是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。
比如,访问下面的网址,http://www.example.com/index.html#print,浏览器实际发出的请求是这样的:GET /index.html HTTP/1.1
Host: www.example.com
1.3.#后的字符
在第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。
比如,下面URL的原意是指定一个颜色值:http://www.example.com/?color=#fff,但是,浏览器实际发出的请求是:GET /?color= HTTP/1.1
Host: www.example.com
1.4.改变#不触发网页重载
单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
比如,从http://www.example.com/index.html#location1改成http://www.example.com/index.html#location2,浏览器不会重新向服务器请求index.html。
1.5.改变#会改变浏览器的访问历史
每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"按钮,就可以回到上一个位置。这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。值得注意的是,上述规则对IE 6和IE 7不成立,它们不会因为#的改变而增加历史记录。
1.6.window.location.hash读取#值
window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。
1.7.onhashchange事件
这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。IE8+、Firefox 3.6+、Chrome 5+、Safari 4.0+支持该事件。
它的使用方法有三种:
- window.onhashchange = func;
- <body onhashchange="func();">
- window.addEventListener("hashchange", func, false);
2.那使用还是不使用 # 呢?
2.1.为什么要去除
Angular官方指出:如果没有足够使用hash风格(#)的理由,还是尽量使用HTML5模式的路由风格;
如果配置了hash风格,在微信支付或是Angular的深路径依然会出404的问题;
当你需要使用GA等工具时,由于无法获取#号后的URL,导致每次路由切换都给其发送一个路径;
'#'有点丑。
2.2.怎样去除?
后端(Tomcat)
Tomcat/conf/web.xml文件上添加
<error-page>
<error-code></error-code>
<location>/</location>
</error-page>
3.带‘#’和不带‘#’原理上有什么区别呢?
3.1.这个得先说下什么是前端路由
以前路由都是后台做的,通过用户请求的url导航到具体的html页面,现在我们在前端可以利用 Angular、vue、react等通过配置文件,达到前端控制路由跳转的功能。
前端路由的实现方法:
通过hash实现 当url的hash发生改变时,触发hashchange注册的回调(低版本没有hashchange事件,通过轮回检测url实现),回调中去进行不同的操作,进行不同的内容展示。
使用hash来实现的话,URI规则中要带上#,路由中#后边的内容就是hash,我们常说的锚点严格来说应该是页面中的a[name]等元素。HTML5的history api操作浏览器的session history实现
基于history实现的路由中不带#,就是原始的路由
3.2 Angular中的路由策略
Angular2 提供的路由策略也是基于上面两个原理实现的,可以在@NgModule中通过providers配置或RouterModule.forRoot()配置:
不使用#:
默认是不使用#(Hash)风格的,即html5路由风格(无#),在无#情况下,后端需要定义能匹配所有页面请求导向index.html页面的路由。
使用 #:
app.module.ts
import { ROUTER_CONFIG } from './app.routes.ts';
@NgModule({
imports: [
RouterModule.forRoot(ROUTER_CONFIG)
// RouterModule.forRoot(ROUTER_CONFIG, { useHash: true } ) 这样写是带#的
],
})或
import { HashLocationStrategy, LocationStrategy } from '@angular/common';@NgModule({
imports:[RouterModule.forRoot(routes)],
providers:[
{provide: LocationStrategy, useClass: HashLocationStrategy}
]
})
3.3.前端路由的优缺点
优点:
- 从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
- 在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户不能获取到想要的url地址,用前端路由做单页面网页就很好的解决了这个问题。
缺点:
- 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。
Angular2+URL中的 # 引发的思考的更多相关文章
- 雷林鹏分享:url中加号引发的错误
刚发现了博客的一个bug,标签页中一些标签带有空格,在url输出中使用了 urlencode 函数进行处理,导致空格被转换成了加号(+),这时通过url访问时会出现错误: 临时解决方法是在urlcod ...
- 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程
简述C#中IO的应用 在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...
- 记一次400错误引发的血案(URL中特殊符号的转义/400 bad request错误)
django+nginx+uwsgi部署的站点访问某个URL时发生了400 bad request的错误,而使用django自带的开发版的web server时没有遇到此问题.初步判断是nginx或u ...
- Spring之LoadTimeWeaver——一个需求引发的思考---转
原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...
- 由SecureCRT引发的思考和学习
由SecureCRT引发的思考和学习 http://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&mid=2652500597&idx=1& ...
- 解决一道leetcode算法题的曲折过程及引发的思考
写在前面 本题实际解题过程是 从 40秒 --> 24秒 -->1.5秒 --> 715ms --> 320ms --> 48ms --> 36ms --> ...
- 【思考】由安装zabbix至排障php一系列引发的思考
[思考]由安装zabbix至排障php一系列引发的思考 linux的知识点林立众多,很有可能你在排查一个故障的时候就得用到另一门技术的知识: 由于linux本身的应用依赖的库和其它环境环环相扣,但又没 ...
- 由<a href = "#" > 引发的思考
原文:由<a href = "#" > 引发的思考 前阵子在一个移动项目中,通过 <a href = "#" > 的方式 绑定clic ...
- 曲演杂坛--一条DELETE引发的思考
原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...
随机推荐
- 【annotation】非人类物种基因组注释(MSU为例)
基因组注释工具ANNOVAR是一款非常好用的注释软件,功能强大,输出数据简单美中不足就是对于非人类物种来说UI不够完善,因此总结一下整个注释的过程,帮助别人快乐自己. 首先我们需要明确我们需要的数据和 ...
- MySQL ERROR 1698 (28000): Access denied for user 'root'@'localhost'
今天在安装MySQL的过程中竟然没有让我输入密码,登录的时候也不需要密码就能进入,这让我很困惑. 进了数据库就设置密码,用了各种方式都不行. 虽然我这数据库没啥东西但也不能没有密码就裸奔啊,有点丢人是 ...
- 问题:Linux报swap空间占用过高,但物理内存还有空余
报错 收到报警,swap空间占用过高,登录到系统查看内存使用详情,看到物理内存还有很多未使用 问题分析 Swap配置对性能的影响分配太多的Swap空间会浪费磁盘空间,而Swap空间太少,则系统会发生错 ...
- python学习之——习题一
习题一:使用while循环输入1 2 3 4 5 6 8 9 10 (不含7) 首先想到,先使用while循环打印出1-10数字,然后再将数字“7”剔除. # 先打印出1-10 n = 1 whi ...
- ArrayList迭代器源码分析
集合的遍历 Java集合框架中容器有很多种类,如下图中: 对于有索引的List集合可以通过for循环遍历集合: List<String> list = new ArrayList<& ...
- Struts2---动态action以及应用
为了处理各种逻辑业务,根据execute方法来判断请求哪种业务,然后将请求转发到对应的业务处理上, 通过动态请求action对象中的方法,实现某个单一的业务逻辑处理. 动态action的应用 //创建 ...
- [IoC容器Unity]第一回:Unity预览
1.引言 高内聚,低耦合成为一个OO架构设计的一个参考标准.高内聚是一个模块或者一个类中成员跟这个模块或者类的关系尽量高,低耦合是不同模块或者不同类之间关系尽量简单. 拿咱国家举例来说,假如你是中国人 ...
- 区间DP 基本题集
51 Nod 1021 石子归并 模板题,敲就完事了,注意一下这种状态转移方程有个四边形的优化(时间) #include <cstdio> #include <iostream> ...
- MySQL存储过程 游标
MySQL存储过程 游标 如何在存储过程中使用MySQL游标来遍历SELECT语句返回的结果集 MySQL游标简介 要处理存储过程中的结果集,请使用游标.游标允许您迭代查询返回的一组行,并相应地处理 ...
- Day 5内存管理,定义变量
昨日内容回顾 python的2种执行方式 交互式 写一句翻译一句 优点:能及时发现bug,及时调试 缺点:关即消失,不能保存 命令行式 优点:可以永久保存 缺点:无法及时看到结果 python3 c: ...