记录一个用vue-cli3.0搭建的项目放到服务器上面去刷新页面导致页面不存在报404的bug

876 阅读4分钟
    今天将自己写的页面放到远程服务器上,(后台管理项目),正常登陆之后,然后进入首页,自己手动点了一下浏览器的那个刷新
    按钮,突然页面就404 not found了,一脸懵逼,然后我重新弄一下,登陆然后点侧边栏去跳转对应的路由,发现一点事没有,只要
    点击浏览器的刷新按钮就会404,然后去百度还有问人,发现原来是在我用vue-cli3.0初始化项目的时候,设置的路由模式是
    history模式导致的。具体原因如下:
    
    1.在项目初始化的时候路由配置有两个模式,一个hash模式一个history模式,简单来说的区别在于url上面带不带#号,这是表面的
    区别,实质的区别在于vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当
    URL改变时,页面不会重新加载。如果不想要很丑的hash,我们可以用路由的 history模式,这种模式充分利
    用 history.pushState API 来完成 URL跳转而无须重新加载页面。
    
    2.下面来细说一下hash模式和history模式的区别,首先我们应该了解一些关于浏览器的机制,比如你在url里面输入这么一个网址
    http://121.46.233.20:9024/index.html,此时浏览器会向服务器发送一个请求,后台会去找有没有index.html这个文件,有的话就
    返回,没有的话就根据后台的配置返回对应的东西。此时我们来看hash模式,hash模式下url里面是有一个#号的,举例来说,比如
    http://121.46.233.20:9024/#/OrganizationManagement,第一步浏览器会根据这个#号前面的第一个/去找到项目里面的index.html
    ,因为在vue-cli3.0项目你打包之后有个dist文件夹,放在了public文件夹里面,里面的那个index.html就是你展示东西的页面,
    因为单页面应用,所有的内容都展示在index.html里面的<div id='app'></div>这个标签里面,第二步发送请求,后台找到这个
    index.html,然后返回给你,第三步vue开始执行,当你发生了路由的跳转那就会去加载对应的路由内容展示出来,/后面的东西其实
    并不是浏览器给你加上去的,而是vue根据路由跳转给你加上的,路由概念在浏览器上不没有的,这是vue里面的概念,不能搞混淆
    了。hash模式下的#号可以理解成一个标记,在浏览器看来,#会被看成一个锚点,是一个可有可无的东西,但是浏览器只认准第一
    个/,这第一个/会被看成是一个页面,是默认页面,如果后面还有/则会看成是另外一个页面,例如/index.html这是一个页面,
    /index/car.html这又是另外一个页面,浏览器才不会知道这是你vue项目里面的一个路由,在vue项目中你跳转执行了push路由跳
    转,vue知道了你路由跳转了将跳转的路由放在了#后面,这步操作是vue执行的并不是浏览器执行的,这点一定要清楚。由于你有了
    一个#号,然后vue是单页面应用,浏览器将会去请求第一个页面也就是第一个/,即index.html页面,所以你用hash模式下,点击浏
    览器刷新功能一直会给你返回index.html,因为这个页面后台可以给你返回,服务器上面有。
    但是此时你用history模式,例如http://121.46.233.20:9024/index,此时跳转到路由比如跳转到
    http://121.46.233.20:9024/OrganizationManagement,如果你页面点击了浏览器刷新了,然后会去请求后台服务器,查找是
    否有OrganizationManagement.html这个页面,显然这个页面并没有,浏览器才不会管你这是不是路由跳转,因为他没有这个路由
    概念,只会觉得这是另外一个页面,所以导致了刷新之后报错404,页面找不到,此时怎么解决呢,也很简单,就是让后台给你配置
    一个如果找不到页面全部返回到index.html上,这样就能保证不会出现404。
    
    归根到底vue是一个单页面应用,在你打包过后所有的东西都是展示在你打包的index.html里面,利用hash模式有个#号能让浏览器
    一直保持是请求的index.html页面,#号之后则是vue自己操作的路由展示上去的一个过程并不是浏览器弄得,你可以认为一个/就
    是一个页面,history模式犹豫没有#号,所以你跳转路由的时候虽然路由变了vue知道是什么意思,但是浏览器不知道,浏览器
    只会根据变化的东西去向服务器请求对应路由的html文件页面,显然服务器没有。
    
    至于怎么配置vue官网也给了一个模板,链接如下:
https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90