vue-router的两种模式Hash和History
单页应用(SPA)采用前端路由成为当前主流,通过改变 URL,在不重新请求页面的情况下,更新视图。目前,主要有两种实现方式:1.hash:利用 URL 中的hash(# 符号)# 代表网页中的一个位置,其右面的字符,就是该位置的标识符。比如:http://www.example.com/index.html#print就代表网页index.html的print位置。浏览器...
单页应用(SPA)采用前端路由成为当前主流,通过改变 URL,在不重新请求页面的情况下,更新视图。目前,主要有两种实现方式:
1.hash:利用 URL 中的hash(# 符号)
# 代表网页中的一个位置,其右面的字符,就是该位置的标识符。比如:
http://www.example.com/index.html#print
就代表网页index.html的print位置。浏览器读取这个 URL 后,会自动将print位置滚动至可视区域。
为网页位置指定标识符的方法有两种:
一、使用锚点,比如<a name="print"></a>
二、使用id属性,比如<div id="print" >
# 本身及其右边字符称之为hash,可通过window.location.hash属性读取,具有如下特点:
# 是用来指导浏览器动作的,对服务器端完全无用。所以,http请求中不包括 #
改变hash,浏览器只会滚动到相应位置,不会重新加载网页
可以为hash的改变添加监听事件:
window.addEventListener("hashchange", funcRef, false)
每一次改变hash,都会在浏览器的访问历史中增加一个记录
利用hash的以上特点,就可以实现前端路由“更新视图但不重新请求页面”的功能了
2.history:利用HTML5 History Interface中新增的方法
History Interface是浏览器历史记录栈提供的接口,通过back(), forward(), go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作。从HTML5开始,History Interface提供了两个新的方法:pushState() 和 replaceState(),使得我们可以对浏览器历史记录栈进行修改:
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会立即发送请求(the browser won't attempt to load this URL after a call to pushState()),这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础
两种模式比较
在一般场景中,hash模式与history模式是差不多的,但几乎所有的文章都推荐使用history模式,理由竟然是:"#" 符号太丑
history与hash相比,存在很多优势(省略百字,见下文链接)
但是,history存在一个问题
对于单页应用来讲,理想的使用场景是仅在进入应用时加载index.html,后续操作通过ajax来完成,不会根据 URL 重新请求页面,但是难免遇到特殊情况,比如用户直接在地址栏中输入并回车,浏览器刷新或者重启
hash模式仅改变hash部分的内容,而hash部分是不会包含在HTTP请求中的:
http://oursite.com/#/user/id // 如重新请求只会发送http://oursite.com/
所以在hash模式下,当 URL 改变时,页面不会重新加载
而在history模式下,URL 就是正常的 URL(建议:前端路由 URL 和后端保持一致)
http://oursite.com/user/id
在此情况下重新(刷新F5)向后端发送请求,如后端没有配置对应/user/id的路由处理,则会返回404错误。
官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
如果这么做,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,你应该在 Vue 应用里面覆盖所有的路由情况,然后再给出一个 404 页面。如果你使用 Node.js 服务器,你可以用服务端路由匹配到来的 URL,并在没有匹配到路由的时候返回 404,以实现回退。
vue官网提供了很多后端配置的例子:https://router.vuejs.org/zh/guide/essentials/history-mode.html#后端配置例子
我当前项目使用 spring 框架,配置也很简单,只需在 web.xml 下添加 error-page 标签
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/404.jsp</location>
</error-page>
特别注意:404.jsp 页面大小 > 1024b
参考
从 vue-router 看前端路由的两种实现:https://zhuanlan.zhihu.com/p/27588422
vue中mode hash 和 history的区别:https://blog.csdn.net/lyn1772671980/article/details/80804419
url中#的作用:https://blog.csdn.net/luka2008/article/details/38753269
解决vue router 使用 history 模式刷新后404问题:https://www.jb51.net/article/119075.htm
web.xml 中 error-page 的正确用法:http://www.cnblogs.com/sharpest/p/6108652.html
vue-router路由使用history模式时,后端如何配置:https://blog.csdn.net/wenmin1987/article/details/81069604
更多推荐
所有评论(0)