Vue-Router中History模式
目录
示例代码托管在:
博客园地址:
华为云社区地址:
history路由
history
模式是指使用html5的historyapi
实现客户端路由的模式,它的典型表现就是去除了hash
模式中url路径中的#
。对于前端路由基本原理还不了解的读者可以看这篇博文。在使用vue-router
时开启history
模式非常容易,只需要在实例化路由时传入mode:'history'
配置项即可,但缺少服务端支持时,基于historyapi
的路由无法从url地址栏直接访问指定页面,这个很容易理解,因为url地址栏里输入后回车相当于发送了一次get
请求,那么不带#
的路由路径就和普通的api
接口是一样的,既然服务端并没有定义这样的接口,那直接访问时出现404页面就很正常了。
官方示例
官方提供了很多处理这种场景的方式,以node.js
版本的处理方案为例:
const http = require('http') const fs = require('fs') const httpport = 80 http.createserver((req, res) => { fs.readfile('index.htm', 'utf-8', (err, content) => { if (err) { console.log('we cannot open "index.htm" file.') } res.writehead(200, { 'content-type': 'text/html; charset=utf-8' }) res.end(content) }) }).listen(httpport, () => { console.log('server listening on: http://localhost:%s', httpport) })
不难看出,它的处理思路就是所有请求都强制重定向到首页,相当于服务端屏蔽了访问资源不存在的情况,而将路由的工作留给客户端自己去处理,这样启用了history
模式的前端路由在直接定位到子页面时就不会报错了。
express中间件
express
工程中使用中间件来处理后端路由的场景,它的使用方式非常简单:
var history = require('connect-history-api-fallback'); var express = require('express'); var app = express(); app.use(history());
源码也只有120行(地址: ),很容易阅读,基本逻辑是只将满足一些特定条件的请求进行重定向,也就是将路由请求和api
请求区分开,重定向的规则可以自定义,路由请求的判断条件包括:
-
get
请求 - headers.accept为
text/html
或*/*
(设置为application/json
或非字符串时会记录错误日志);
核心逻辑就是82-85行的:
rewritetarget = options.index || '/index.html'; logger('rewriting', req.method, req.url, 'to', rewritetarget); req.url = rewritetarget; next();
也就是如果匹配到自定义的重定向规则就使用自定义场景,否则就使用/index.html
作为默认值,然后重写req.url
属性,接着进入下一个中间件执行其他逻辑。
客户端兜底404
当服务端重定向后,如果没有进行ssr
的同构路由定制,对于所有路由请求都会返回index.html
页面,此时如果需要使用404页面,就需要在客户端路由中设定一个优先级最低的兜底路由,由于优先级的缘故,它不会影响其他精确匹配的路由配置:
const router = new vuerouter({ mode: 'history', routes: [ { path: '*', component: notfoundcomponent } ] })
上一篇: void 0 与 undefined
下一篇: js-05-对象(object)