查看: 89|回复: 0

vue路由模式及 history 模式下服务端配置

[复制链接]

2

主题

3

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2022-9-21 17:36:50 | 显示全部楼层 |阅读模式
前言

vue 项目中,我们比较常用的模式为 hash 和 history 模式 默认情况下,vue 项目默认采用的就是 hash 模式,Vue-router 中hash模式和history模式的区别(点击进入), 有些人对 history 模式下,为什么需要服务器做相应配置,以及如何配置不甚理解,所以这篇文章就对此做出分析,重点是让大家理解,为什么 history 模式下需要服务器做配置 这里会对 hash 模式和 history 模式都做出说明,通过对比,才能更好的理解我们的行为。
1. hash 模式

1.1 什么是 hash 模式

先从一个熟悉的锚标记案例开始,帮助大家理解 hash 模式是怎么回事
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        ul {
            list-style-type: none;
        }

        li {
            line-height: 30px;
        }

        div {
            height: 800px;
        }
    </style>
</head>

<body>
    <ul>
        <li><a href="#lish">历史沿革</a></li>
        <li><a href="#mingren">名人典故</a></li>
        <li><a href="#jinri">今日发展</a></li>
        <li><a href="#weilai">未来规划</a></li>
    </ul>

    <div id="lish">
        <h3>历史沿革</h3>
        历史沿革历史沿革历史沿革历史沿革历史沿革历史沿革历史沿革历史沿革
    </div>
    <div id="mingren">
        <h3>名人典故</h3>
        名人典故名人典故名人典故名人典故名人典故
    </div>
    <div id="jinri">
        <h3>今日发展</h3>
        今日发展今日发展今日发展今日发展今日发展今日发展
    </div>
    <div id="weilai">
        <h3>未来规划</h3>
        未来规划未来规划未来规划未来规划未来规划未来规划未来规划未来规划
    </div>
</body>

</html>运行效果如下图



总结:

  • 点击链接时,没有跳转到其他页面
  • 点击连接时,在当前页面内进行跳转
  • 点击连接时,地址栏中 # 后面的部分发生变化
这个 # 后面的部分就叫做 hash
http
:
//127.0.0.1:5500/hash.html#weilai如下面的代码
<a

href
=
"#lish"
>
历史沿革
</a>当超链接的 href 值不是某个页面,而是使用 hash 值时,是不会发生页面跳转的,这点很重要
vue-router 就是利用了这个特点,实现了地址栏的 hash 值发生变化后,切换不同的组件进行渲染
1.2 hash 模式特点

在浏览器支持度上面,Hash 模式是比较强势的,甚至能兼容低版本的 IE 浏览器
唯一的缺点就是长得丑
2. history 模式

HTML5 History API 提供了一个 history.pushState 和 history.replaceState 方法(浏览器支持情况不是很乐观),它能让开发人员在不刷新网页的情况下改变站点的 URL
我们这里不去详细解释HTML5 History API
通过如下配置,就可以开启 vue-router 的 history 模式
const router = new VueRouter({
  routes,
  mode: 'history',
})地址栏中的地址如下
http
:
//localhost:8081/food没有了 hash ,长得确实顺眼多了
3. history 模式的问题

history 模式很好,长得很漂亮,但是漂亮的人一般都不好养
在生产环境中,history 模式有一个比较大的问题,就是当手动刷新时,会报404错误
我们来演示一遍,看下面的动图



我们复盘一下刚才的操作
① 地址栏中输入http://localhost:8080/douyin/,页面正常显示,上方导航可以看到,但是没有具体内容,因为路由规则中没有匹配 “/”
② 依次点击几个导航,都可以正常切换,点击播放进入到详情页也没有问题
③ 当地址栏中地址变成 http://localhost:8080/douyin/knowledge 时(knowledge也可以换成quadratic、food),此时手动刷新页面(在地址栏中敲击回车或者F5刷新),页面最后就报404了



④ 如果路由模式为 hash 模式,就不会出现上面的问题,大家可以自己尝试
4. 寻找原因

无论是 hash 模式,还是 history 模式,浏览器中输入如下地址
http
:
//localhost:8081/douyin浏览器一定会像服务端发送一个请求



我们也知道,默认请求的一定是目录下的 index.html(这个是很多服务器的默认设置)
而 index.html 中引用了 js、css 等文件,所以我们看下面又请求了其他一些资源
所以,我们可以看到这样的页面



当我们点击页面中的导航时
如果是 hash 模式,当地址栏中的 hash 发生改变时,浏览器不会向服务端发送请求,所以会匹配路由规则,进而进行组件切换
如果是 history 模式,点击导航,地址栏发生变化后,会利用 h5 的 history API进行导航,浏览器也不会向服务器发送请求
但是,当我们浏览到某个地址下时,如 http://localhost:8080/douyin/knowledge(在 hash 模式下,地址为 http://localhost:8080/douyin/#/knowledge),在地址栏中敲击回车,或者刷新页面时,两者的行为就不一样了
1、hash 模式
hash 模式下下,只将 hash 前面的部分当作地址,所以会向服务端重新请求 http://localhost:8080/douyin/,服务端仍然会返回 index.html,此文件再下载引入的 js、css 等文件,然后根据地址栏中的 hash 值匹配路由,所以刷新之后,与刷新之前的页面内容是一致的(因为 hash 值没有变化)



2、history 模式
history 模式下,会将地址栏中的地址全部看作请求地址,所以刷新后,会向服务端请求这个地址



而我们的前端项目下,只有一个 index.html 和一些 js、css、图片等文件,根本没有请求的资源,所以服务器就返回 404了
我这里使用的是 http-server 这个简单的服务器,其他服务器的行为基本一致,如 nginx 返回的 404 如下所示



总结:现在我们找到了 history 模式下出现404的原因,也理解了 hash 模式和 history 模式之间的区别
5. 解决方案

问题既然找到了,解决起来自然就有思路了
为了更加贴近实际,我们这次的服务器使用 nginx
首先将 douyin 项目拷贝到 nginx 的根目录下,然后打开 nginx 的配置文件(这里选择的是Nginx1.15.11\conf\vhosts\0localhost_80.conf),添加如下一行配置



try_files $uri $uri
/ /
admin
/
index
.
html
;上面代码的作用是,配置url重写语句,注意是重写,不是重定向
不改变url的情况重写浏览器内容,重写到index.html,因为这个index.html使我们项目的入口,index.html里面会读取当时打包好的app.js,就可以读取到路由配置,以实现我们浏览器的url对应的路由页面
重启 nginx,然后随意刷新浏览器,再也不会出现404 问题了



如图上注释所说:
① 浏览器请求 http://localhost/douyin/knowledge nginx 发现没有资源,所以返回404
② nginx 紧接着又将 index.html 返回,浏览器加载后,又去加载其中引用的 js、css 等文件,然后路由规则根据地址栏中的地址,去匹配对应的组件进行渲染
6. 路由模式总结

hash 模式除了长得丑点外,优点还是很多的,比如不需要服务器配置,兼容性好等,所以像 网易云音乐等都在使用;
history 颜值出众,但是服务器需要做些配置,但是也不复杂;
这里的服务器与前后端分离开发中的服务器端不是一个概念,那个指的是 java、php 等后端服务;
这里的服务器指的是前端项目部署的服务器,如 nginx、apache等,所以需要在这些服务器的配置文件中做配置。

— THE END —

【免责声明】图文来自网络,版权归原作者所有。如侵权请联系删除;我们对文中观点保持中立,仅供参考、交流之目的。
推荐阅读

  • 高危!Fastjson反序列化漏洞风险通告
  • OpenSSL多个安全漏洞(远程代码执行漏洞和拒绝服务漏洞)预警,CVE-2022-1292和CVE-2022-1473
  • 一款低延迟、跨平台的远程控制软件,Parsec
  • 27年IE终落幕,再见IE,你好Edge
  • 谷歌Flutter 3.0正式发布:稳定支持6大平台(iOS、Android、Web、Windows、macOS、Linux )
  • Python 3.11 性能测评超 3.10 近 64%
  • 截图工具推荐
  • 比Chrome快3倍,更安全、快速且私密的网络浏览器,Brave Browser(开源、免费、跨平台)
  • Navicat Premium 16.0.12 Mac中文版 全能的Mac数据库管理与开发工具
  • 甲骨文修复 Java “年度加密漏洞” (CVE-2022-21449),影响 Java 15 及以上版本
  • 2022版首发,阿里Java开发手册(黄山版),新增11条规约
  • 16款超好用的Edge插件,让你的浏览器瞬间开挂!
微信8.0将好友放开到了一万,宝宝们可以加我大号了,先到先得。

扫描下方二维码即可加我微信啦,2022,抱团取暖,一起牛逼。

产品+技术统称为大技术。分享优秀产品,传播产品思维;专注技术分享,包含JS、CSS、 HTML5、Vue、React、Augula、View UI(iView)、Element UI、Flutter、Electron和JAVA、JVM、SpringBoot、Dubbo、Spring Cloud/Alibaba、Docker、Docker Compose、K8S等实用技术与框架。



请我
分享、
赞、在看
本文来自公众号:大技术
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表