背景:
我的项目是部署在服务器的指定目录下,并且项目的路由模式是history模式,所以我需要在vue.config中配置publicpath和在路由中配置base,配置为相同的字符串,并告诉后端ng映射到我设置的这个字符串上.,此时访问地址可以显示项目页面,但是部分window.open()方法所跳转到的页面会报错404.
报错代码:
window.open('/XXXX/XXXX', "_blank");
假设我项目设置的vue.config中配置publicpath和在路由中配置base为:'/ABC/',且后端ng也配置了映射"/ABC/"
对于我的这种情况,是因为我的window.open使用的是简易写法:
window.open('/XXXX/XXXX', "_blank");
所以,浏览器会直接新开一个窗口,将我输入的url地址作为绝对地址给打开,这时候,在history模式下,当我使用window.open()
方法跳转到非路由路径时,浏览器会尝试从服务器获取该路径的资源,但由于没有匹配到任何路由,服务器会返回404错误。(window.open方法没自动带上'/ABC/',而是直接打开了'/xxxx/xxxx',相当于直接访问根目录,因为我的资源放在'/ABC/目录下',所以是访问不到的)
那为什么我们this.$route.push()不会404?
因为我说了前提条件,我的路由配置了base:'/ABC/',路由跳转会自动强写路由基地址到路径,也就是相当于我们的http请求基地址一样,拼接到请求路径前面,那么this.$router.resolve()
方法会自动给我们this.$route.push(‘path’)里面写的path前面加上:'/ABC/',所以这样就可以访问到正确的目录。
那是不是每次window.open手动给他加上前缀"/ABC/"就可以了?
是的,但是这样很麻烦,每次都要手动加,那有没有简易方法?
解决方案:
我们可以通过this.$router.resolve()
方法,其与路由配置会进行合并,这样就可将路径与路由的配置相结合.
1. const { href } = this.$router.resolve({ 2. path: `/XXXX/XXXX` 3. }); 4. window.open(href, "_blank");
这样this.$router.resolve(),方法会自动将路由中的base给拼接到path前面,我们window.open()路由页面就不会404了.
同时,window.open()方法也可以携带参数:
1. const { href } = this.$router.resolve({ 2. path: '/XXXX', query: { 3. appid: this.appid, 4. modelId: modelId 5. } 6. }); 7. window.open(href, '_blank');