开发环境:vue-router history模式页面404踩坑

4,075 阅读2分钟

场景:今天后端的同学跟我说,url的路由携带了 # 觉得很难看,让我修改一下,我心里一想:就这?我一行代码就全部搞定了。

mode:'history' 这我不到一分钟就修改完了,然后直接甩给后端一个开发环境的url。结果,不到一分钟,后端同学说:你这路由不行呀,为什么我刷新一下页面,页面怎么丢失了!故事就这样开始了......

开发环境相关配置

    // router.js
    const router = new VueRouter({
        mode: 'history',
        routes
    });

  // vue.config.js
  // 开发环境需要解决跨域的问题,所以配置了如下的代码
  
    devServer:{
       proxy: {
          '/': {
            target: 'http://localhost:3000',
          },
        },
    }

问题排查

  • 经过前几个vue项目的开发,我依稀记得开发环境是用history是不会将页面丢失的呀,然后翻了一下vue-cli的文档,在开发环境中脚手架帮我们重定向到了index.html,所以排除这一条环境的问题。
  • 打开浏览器,我仔细看了一下404这个页面,发现页面并没有这样简单

0.png requested URL 找不到,转瞬即逝,我突然想到,是不是因为我开了Proxy代理,将这个页面代理到服务端,然后就去找相应的路由,因为没有找到所以返回Not Found,于是我注释掉了proxy对象,果真,页面刷新不会丢失页面了,随后我就在想这是为什么呢?

proxy代理

  • 我的理解:只要你当前网页发出非法请求并且与proxy配置的别名相同,则会被proxy进行代理
  • 刷新页面之后为什么访问 / 可以,但是访问 /about则404呢?因为访问 / 能够命中当前根目录下的index.html,而访问 /about 则不能命中 /about/index.html,访问 /about 则是非法请求,所以被proxy代理

解决方案

  • 官方标准的解决方案
module.exports = {
  //...
  devServer: {
    proxy: {
      '/': {
        target: 'http://localhost:3000',
        // 只需要添加该方法,然后当请求的是html,则重定向到index.html
        bypass: function (req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    },
  },
};

记录自己日常遇见的问题,感谢阅读!