Angular.JS去掉访问路径URL中的#号详解


Posted in Javascript onMarch 30, 2017

本文目录

  • URL的#号问题
  • 找到错误原因
  • 静态网站的解决方案
  • 动态网站的解决方案

一、 URL的#号问题

使用AngularJS的朋友都应该了解,AngularJS框架定义了自己的前端路由控制器,通过不同URL实现单面(ng-app)对视图(ng-view)的部署刷新,并支持HTML5的历史记录功能,详细介绍可以参考文章:AngularJS路由和模板。

对于默认的情况,是不启动HTML5模式的,URL中会包括一个#号,用来区别是AngularJS管理的路径还是WebServer管理的路径。

比如:下面的带#号的URL,是AngularJS管理的路径。

http://onbook.me/
http://onbook.me/#/
http://onbook.me/#/book
http://onbook.me/#/about

这种体验其实是不太友好的,特别是像我这种喜欢简洁设计的人,#号的出现非我自愿的,怎么看怎么难受。AngularJS框架提供了一种HTML5模式的路由,可以直接去掉#号。

通过设置$locationProvider.html5Mode(true)就行了。

book.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

 //..省略代码
 $locationProvider.html5Mode(true);
}]);

支持HTML5的路由URL。

http://onbook.me/
http://onbook.me/book
http://onbook.me/about

接下来的问题就来了,当用这种方式设置了路径以后。如果用户从首页(http://onbook.me/)开始访问,然后跳转到 图书页(http://onbook.me/book)一切正常。但如果用户直接打开 图书页(http://onbook.me/book) ,就会出现404错误。

Angular.JS去掉访问路径URL中的#号详解

就是这个问题纠结了我好长时间,让我不得不用带#号的URL。

二、找到错误原因

那么,这个问题的原因出在哪里了呢? 在路径解析上出错了。

让我从头说起,AngularJS是单页应用,一个ng-app对应一个页面,一个URL。AngularJS实现了自己的前端路由,让一个ng-app可以管理多个URL,再对应到多个ng-vew上面。当我们去访问URL(http://onbook.me/book) 的时候,怎么确定这个路径是 WebServer 后台管理的URL还是AngularJS前台管理的URL呢?

分2种情况看:

      1. 用户如果是先访问 首页(http://onbook.me),然后再跳转到 页面(http://onbook.me/book),则这个跳转是由AngularJS前台管理的URL,访问是正常的。

      2. 用户直接访问 页面(http://onbook.me/book)时,请求是先被提交到了WebServer后台,后台路由没有对应页面(http://onbook.me/book)的路由管理,就会出现404的错误。

如果能把这层想明白,技术上就非常容易解决了。我们让WebServer把属于AngularJS管理的路由URL,都发转到ng-app就可以解决404的问题了,同时,没有#号,还支持HTML5的历史记录查询!!

实现起来分为2种解决方案:

      1. 静态网站:纯前台网站(JS+HTML+CSS),通过Nginx提供Web服务。

      2. 动态网站:前台(JS + HTML + CSS) + 后台Node.js提供Web服务。

三、静态网站的解决方案

静态网站,我们需要修改的地方包括3个文件

      index.html : ng-app的定义文件

      app.js : 对应ng-app的控制文件

      nginx.conf : nginx的网站配置文件

编辑 index.html,增加base标签。

<html lang="zh-CN" ng-app="book">
<head>
 <base href="/" rel="external nofollow" >
 
// 省略代码
</head>

编辑app.js,增加 $locationProvider.html5Mode(true);

book.config(['$routeProvider', '$locationProvider', '$sceProvider', 'tplProvider', function ($routeProvider, $locationProvider, $sceProvider, tplProvider) {
 $routeProvider
 .when('/', {templateUrl: tplProvider.html('welcome'), controller: 'WelcomeCtrl'})
 .when('/book', {templateUrl: tplProvider.html('book'), controller: 'BookCtrl'}) //图书
 .when('/book-r1', {templateUrl: tplProvider.html('book-r1'), controller: 'BookR1Ctrl'}) //R的极客理想
 .when('/video', {templateUrl: tplProvider.html('video'), controller: 'VideoCtrl'}) //视频
 .when('/about', {templateUrl: tplProvider.html('about'), controller: 'AboutCtrl'}) //关于作者
 .otherwise({redirectTo: '/'});
 $locationProvider.html5Mode(true);
}]);

编辑nginx的配置文件,增加try_files配置。

server {
 set $htdocs /www/deploy/mysite/onbook;
 listen 80;
 server_name onbook.me;
 location / {
 root $htdocs;
 try_files $uri $uri/ /index.html =404;
 }
}

这样,静态网站就搞定了,没有麻烦的#号了,可以直接访问和任意页面的刷新。

四、动态网站的解决方案

动态网站,我们同样需要修改的地方包括3个文件。

      index.html : ng-app的定义文件

      app.js : 对应ng-app的控制文件

      server.js : Express框架的路由访问控制文件

index.html 和 app.js两个文件修改,同静态网站的解决方案。动态网站,一般不是通过Nginx直接路由,而是通过Web服务器管理路由。假设我们使用的是Node.js的Express的Web框架。

打开Express框架的路由访问控制文件server.js,增加路由配置。

app.use(function (req, res) {
 console.log(req.path);
 if(req.path.indexOf('/api')>=0){
 res.send("server text");

 }else{ //angular启动页
 res.sendfile('app/index.html');
 }
});

设置当 站内路径(req.path) 不包括 /api 时,都转发到 AngularJS的ng-app(index.html)。所以,我们再直接访问地址 (http://onbook.me/book)时,/book 不包括 /api,就会被直接转发到AngularJS进行路由管理。我们就实现了路由的优化!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JavaScript 判断日期格式是否正确的实现代码
Jul 04 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
Jan 15 Javascript
JavaScript对象的property属性详解
Apr 01 Javascript
自定义函数实现IE7与IE8不兼容js中trim函数的问题
Feb 03 Javascript
jQuery插件支持同一页面被多次调用
Feb 14 Javascript
简单掌握JavaScript中const声明常量与变量的用法
May 21 Javascript
函数四种调用模式以及其中的this指向
Jan 16 Javascript
Map.vue基于百度地图组件重构笔记分享
Apr 17 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
Dec 25 Javascript
layui内置模块layim发送图片添加加载动画的方法
Sep 23 Javascript
基于Vue+ElementUI的省市区地址选择通用组件
Nov 20 Javascript
JS typeof fn === 'function' &amp;&amp; fn()详解
Aug 22 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
Mar 30 #Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
Mar 30 #Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 #Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
Mar 30 #Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
Mar 30 #Javascript
JavaScript mixin实现多继承的方法详解
Mar 30 #Javascript
Angular.JS中的指令引用template与指令当做属性详解
Mar 30 #Javascript
You might like
MySQL数据源表结构图示
2008/06/05 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
PHP strstr 函数判断字符串是否否存在的实例代码
2013/09/28 PHP
一个基于phpQuery的php通用采集类分享
2014/04/09 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
仿微博字符限制效果实现代码
2012/04/20 Javascript
js自定义事件及事件交互原理概述(一)
2013/02/01 Javascript
jquery中邮箱地址 URL网站地址正则验证实例代码
2013/09/15 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
深入学习JavaScript对象
2015/10/13 Javascript
不得不分享的JavaScript常用方法函数集(上)
2015/12/23 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
微信小程序 WebSocket详解及应用
2017/01/21 Javascript
Express URL跳转(重定向)的实现方法
2017/04/07 Javascript
echarts学习笔记之图表自适应问题详解
2017/11/22 Javascript
vue组件间的参数传递实例详解
2019/04/26 Javascript
vue - props 声明数组和对象操作
2020/07/30 Javascript
微信小程序实现滚动Tab选项卡
2020/11/16 Javascript
[03:41]DOTA2上海特锦赛小组赛第三日recap精彩回顾
2016/02/28 DOTA
[35:29]Secret vs VG 2018国际邀请赛淘汰赛BO3 第三场 8.23
2018/08/24 DOTA
Python读取word文本操作详解
2018/01/22 Python
django如何连接已存在数据的数据库
2018/08/14 Python
Python列表操作方法详解
2020/02/09 Python
Django 解决阿里云部署同步数据库报错的问题
2020/05/14 Python
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
应聘自荐书
2013/10/08 职场文书
采购员的工作职责
2013/12/26 职场文书
入党自我评价优缺点
2014/01/25 职场文书
学校社会实践活动总结
2014/07/03 职场文书
2014光棍节单身联谊活动策划书
2014/10/10 职场文书
2014年大学团支部工作总结
2014/12/02 职场文书
毕业典礼主持词
2015/06/29 职场文书
银行服务理念口号
2015/12/25 职场文书
大学学生会主席竞选稿怎么写?
2019/08/19 职场文书
详解JAVA的控制语句
2021/11/11 Java/Android