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 面向对象全新理练之数据的封装
Dec 03 Javascript
解决Extjs上传图片无法预览的解决方法
Mar 22 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
Oct 17 Javascript
jQuery 移动端artEditor富文本编辑器
Jan 11 Javascript
js封装tab标签页实例分享
Dec 19 Javascript
node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小
Jan 20 Javascript
Mongoose经常返回e11000 error的原因分析
Mar 29 Javascript
详解vue-cil和webpack中本地静态图片的路径问题解决方案
Sep 27 Javascript
使用Bootrap和Vue实现仿百度搜索功能
Oct 26 Javascript
JavaScript ES6箭头函数使用指南
Dec 30 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
Mar 16 Javascript
Vue实现动态查询规则生成组件
May 27 Vue.js
详解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
浅析php header 跳转
2013/06/17 PHP
解析PHP将对象转换成数组的方法(兼容多维数组类型)
2013/06/21 PHP
PHP实现的AES双向加密解密功能示例【128位】
2018/09/03 PHP
PHP将整数数字转换为罗马数字实例分享
2019/03/17 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
PHP命名空间定义与用法实例分析
2019/08/14 PHP
事件模型在各浏览器中存在差异
2010/10/20 Javascript
jquery $.ajax相关用法分享
2012/03/16 Javascript
原生JavaScript实现合并多个数组示例
2014/09/21 Javascript
javascript实现拖动元素交换位置
2015/11/29 Javascript
JavaScript知识点总结之如何提高性能
2016/01/15 Javascript
jQuery根据表单name获取值的方法
2016/05/24 Javascript
JS实现点击事件统计的简单实例
2016/07/10 Javascript
jquery实现左右轮播图效果
2017/09/28 jQuery
微信小程序返回多级页面的实现方法
2017/10/27 Javascript
vue实现学生录入系统之添加删除功能
2018/07/11 Javascript
JS原生瀑布流效果实现
2019/04/26 Javascript
js实现星星打分效果
2020/07/05 Javascript
Python的Django框架中使用SQLAlchemy操作数据库的教程
2016/06/02 Python
由浅入深讲解python中的yield与generator
2017/04/05 Python
python判断一个数是否能被另一个整数整除的实例
2018/12/12 Python
Python调用scp向服务器上传文件示例
2019/12/22 Python
丝芙兰美国官网:SEPHORA美国
2016/08/03 全球购物
explicit和implicit的含义
2012/11/15 面试题
早餐连锁店计划书
2014/01/08 职场文书
行政助理的岗位职责
2014/02/18 职场文书
新闻传媒系求职信范文
2014/04/19 职场文书
合作意向书
2014/07/30 职场文书
乡镇党委书记个人整改措施
2014/09/15 职场文书
2015年元旦联欢晚会活动总结
2014/11/28 职场文书
Python爬虫基础之爬虫的分类知识总结
2021/05/13 Python
pandas提升计算效率的一些方法汇总
2021/05/30 Python
vue.js Router中嵌套路由的实用示例
2021/06/27 Vue.js
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫
铁拳制作人赞《铁拳7》老头环Mod:制作精良 但别弄了
2022/04/03 其他游戏
Python安装使用Scrapy框架
2022/04/12 Python