hash和history路由的区别 - 爱喝酸奶的吃货
source link: https://www.cnblogs.com/yingzi1028/p/16331300.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在了解路由模式前,我们先看下 什么是单页面应用,vue-router 的实现原理是怎样的,这样更容易理解路由。
SPA与前端路由
SPA(单页面应用,全程为:Single-page Web applications)指的是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序,简单通俗点就是在一个项目中只有一个html页面,它在第一次加载页面时,将唯一完成的html页面和所有其余页面组件一起下载下来,所有的组件的展示与切换都在这唯一的页面中完成,这样切换页面时,不会重新加载整个页面,而是通过路由来实现不同组件之间的切换。
单页面应用(SPA)的核心之一是:更新视图而不重新请求页面。
vue Router实现原理
vue-router 在实现单页面路由时,提供了两种方式:Hash 模式和 History 模式;vue2是 根据 mode 参数来决定采用哪种方式,默认是 Hash 模式,手动设置为 History 模式。更新视图但不重新请求页面”是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有以下两种方式
- vue-router 默认为hash模式,使用URL的 hash 来模拟一个完整的URL,当URL改变时,页面不会重新加载;# 就是 hash符号,中文名为哈希符或者锚点,在 hash 符号后的值称为 hash 值。
- 路由的 hash 模式是利用了 window可以监听onhashchange 事件来实现的,也就是说 hash 值是用来指导浏览器动作的,对服务器没有影响,HTTP 请求中也不会包括 hash 值,同时每一次改变 hash 值,都会在浏览器的访问历史中增加一个记录,使用“后退”按钮,就可以回到上一个位置。所以,hash模式 是根据 hash 值 来发生改变,根据不同的值,渲染指定DOM位置的不同数据。
参考:Vue 前端路由工作原理,hash与history之间的区别
- url中带一个 # 号
- 可以改变URL,但不会触发页面重新加载(hash的改变会记录在 window.hisotry 中)因此并不算是一次http请求,所以这种模式不利于SEO优化
- 只能修改 # 后面的部分,因此只能跳转与当前URL同文档的URL
- 只能通过字符串改变URL
- 通过 window.onhashchange 监听 hash 的改变,借此实现无刷新跳转的功能。
- 每改变一次 hash ( window.location.hash),都会在浏览器的访问历史中增加一个记录。
- 路径中从 # 开始,后面的所有路径都叫做路由的
哈希值,
并且哈希值它不会作为路径的一部分随着http请求,发给服务器
History
- history 是路由的另一种模式,在相应的 router 配置时将 mode 设置为 history 即可。
- history 模式是通过调用 window.history 对象上的一系列方法来实现页面的无刷新跳转。
- 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。
- 这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
- 新的URL可以是与当前URL同源的任意 URL,也可以与当前URL一样,但是这样会把重复的一次操作记录到栈中。
- 通过参数stateObject可以添加任意类型的数据到记录中。
- 可额外设置title属性供后续使用。
- 通过pushState、replaceState实现无刷新跳转的功能。
- 路径直接拼接在端口号后面,后面的路径也会随着http请求发给服务器,因此前端的URL必须和向发送请求后端URL保持一致,否则会报404错误。
- 由于History API的缘故,低版本浏览器有兼容行问题。
生产环境存在问题
因为 history 模式的时候路径会随着 http 请求发送给服务器,项目打包部署时,需要后端配置 nginx,当应用通过 vue-router 跳转到某个页面后,因为此时是前端路由控制页面跳转,虽然url改变,但是页面只是内容改变,并没有重新请求,所以这套流程没有任何问题。但是,如果在当前的页面刷新一下,此时会重新发起请求,如果 nginx 没有匹配到当前url,就会出现404的页面。
上文已讲,hash 虽然可以改变URL,但不会被包括在 HTTP 请求中。它被用来指导浏览器动作,并不影响服务器端,因此,改变 hash 并没有改变URL,所以页面路径还是之前的路径,nginx 不会拦截。 因此,切记在使用 history 模式时,需要服务端允许地址可访问,否则就会出现404的尴尬场景。
那为什么开发环境时就不会出现404呢?
因为在 vue-cli
中 webpack
帮我们做了处理
生产环境 刷新 404 的解决办法可以在 nginx
做代理转发,在 nginx 中配置按顺序检查参数中的资源是否存在,如果都没有找到,让 nginx 内部重定向到项目首页。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK