VUE的路由模式
hash: 使用 URL hash 值来作路由。默认模式。
- history: 依赖 HTML5 History API 和服务器配置。
- abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端
- abstract模式是使用一个不依赖于浏览器的浏览历史虚拟管理后端。
根据平台差异可以看出,在 Weex 环境中只支持使用 abstract 模式。 不过,vue-router 自身会对环境做校验,如果发现没有浏览器的 API,vue-router 会自动强制进入 abstract 模式,所以 在使用 vue-router 时只要不写 mode 配置即可,默认会在浏览器环境中使用 hash 模式,在移动端原生环境中使用 abstract 模式。 (当然,你也可以明确指定在所有情况下都使用 abstract 模式)。
hash
hash:即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。比如这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
hash 实现原理
hash模式背后的原理是
onhashchange
事件,可以在window
对象上监听这个事件:
function goToSet(){
location.hash = "red";
}
function goToHome(){
location.hash= "yellow";
}
function goBack(){
history.go(-1);
}
// onhashchange:当地址栏hash变化时触发;
window.onhashchange = function(event){
console.log(event);
console.log(location);
//
const hash = location.hash.slice(1);
//
document.body.style.backgroundColor = hash;
}
更关键的一点是,因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来,后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配。
history
随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由。
history api可以分为两大部分:切换和修改
(1)切换历史状态
包括back
、forward
、go
三个方法,对应浏览器的前进,后退,跳转操作。
history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进
(2)修改历史状态
包括了pushState、replaceState
两个方法,这两个方法接收三个参数:stateObj,title,url。
history实现原理
function goBack(){
history.go(-1);
}
function goToSet(){
//
history.pushState({color:"red"},"red","red");
document.body.style.backgroundColor = "red";
}
function goToHome(){
history.pushState({color:"yellow"},"yellow","yellow");
document.body.style.backgroundColor = "yellow";
}
// pushstate后,前进forward后退back时,可以触发
window.onpopstate= function(event){
console.log(event);
document.body.style.backgroundColor = event.state.color;
}
通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。
通过history api,我们丢掉了丑陋的#,但是它也有个毛病:
不怕前进,不怕后退,就怕刷新,f5,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的。
在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题。但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。
history路由模式下,如何防止刷新404
connect-history-api-fallback中间件很好的解决了这个问题。具体来说,每当出现符合以下条件的请求时,它将把请求定位到你指定的索引文件(默认为/index.html)。
请求是Get请求
请求的Content-Type类型是text/html类型
不是直接的文件请求,即所请求的路径不包含.(点)字符
不匹配option参数中提供的模式
使用方法
npm install --save connect-history-api-fallback
下面主要介绍下在express中的使用方法:
var history = require('connect-history-api-fallback');
var express = require('express');
var app = express();
app.use(history());
在express中使用的时候需要注意一点的是,该中间件必须要放在express.static中间前的前面引入,否则会出现问题