浅谈路由hash & history

128 阅读3分钟

路由有两种模式: hash 和 history

1 hash 哈希 --#开头

通常用于页面内导航 或者锚点

当哈希变化页面不会重新加载 ,而是触发hashChange事件

image.png

2 history

history.pushState() history.replaceState() history.back() 通过pushState、replaceState实现无刷新跳转的功能 ,上述方法添加 替换 或者移动历史记录 并不会导致页面实际刷新 当历史记录发生变化 浏览器不会重新加载页面 但可以通过popState捕获变化并做出响应

umi中封装了history

image.png

注意:

3.两者选择

在实际的项目中,如何选择:

  • to B 的系统推荐用 hash ,相对简单且容易使用,且因为 hashurl 规范不敏感;

  • to C 的系统,可以考虑选择 H5 history ,但是需要服务端支持

  • 能先用简单的,就别用复杂的,要考虑成本和收益

4. 生产环境存在的问题

       因为  history  模式的时候路径会随着  http 请求发送给服务器,项目打包部署时,需要后端配置 nginx,当应用通过  vue-router  跳转到某个页面后,因为此时是前端路由控制页面跳转,虽然url改变,但是页面只是内容改变,并没有重新请求,所以这套流程没有任何问题。但是,如果在当前的页面刷新一下,此时会重新发起请求,如果  nginx  没有匹配到当前url,就会出现404的页面。

那为什么hash模式不会出现这个问题呢? hash 虽然可以改变URL,但不会被包括在  HTTP  请求中。它被用来指导浏览器动作,并不影响服务器端,因此,改变  hash  并没有改变URL,所以页面路径还是之前的路径,nginx  不会拦截。 因此,切记在使用  history  模式时,需要服务端允许地址可访问,否则就会出现404的尴尬场景。

另外一种表达是 - 使用 history 模式时,在对当前的页面进行刷新时,此时浏览器会重新发起请求。如果 nginx 没有匹配得到当前的 url ,就会出现 404 的页面。

  • 而对于 hash 模式来说, 它虽然看着是改变了 url ,但不会被包括在 http 请求中。所以,它算是被用来指导浏览器的动作,并不影响服务器端。因此,改变 hash 并没有真正地改变 url ,所以页面路径还是之前的路径, nginx 也就不会拦截。

  • 因此,在使用 history 模式时,需要通过服务端来允许地址可访问,如果没有设置,就很容易导致出现 404 的局面。

 那为什么开发环境时就不会出现404呢?

因为在 vue-cli  中  webpack  帮我们做了处理

 

 解决问题

生产环境 刷新 404 的解决办法可以在 nginx  做代理转发,在  nginx 中配置按顺序检查参数中的资源是否存在,如果都没有找到,让   nginx  内部重定向到项目首页。