关于vue-router路径计算问题


Posted in Javascript onMay 10, 2017

昨天刚刚发表了一个前端跨域新方案尝试,今天在开发中就遇到的了问题。

起因

前端使用的是vue-router组件的history模式,但是由于我们的整个页面都是从static(静态资源站)load过来的,所以其他页面自然也需要跨域去拿,然而就在跨域的时候 vue-router 出了问题。

分析问题

我们的api站点在 api.com

而静态资源在 static.com,页面的base标签也指向static

<base href="http://static.com" rel="external nofollow" />

然而,在访问 test模板时却跳到了http://api.com/http:/static.com/test

经过一些简单的断点调试,锁定了以下代码

[source]: https://github.com/vuejs/vue-router/blob/dev/dist/vue-router.esm.js

 [vue-router.esm.js][source]

//1794行~1675行
function normalizeBase (base) {
 if (!base) {
  if (inBrowser) {
   // respect <base> tag
   var baseEl = document.querySelector('base');
   base = (baseEl && baseEl.getAttribute('href')) || '/';
  } else {
   base = '/';
  }
 }
 // make sure there's the starting slash
 if (base.charAt(0) !== '/') {
  base = '/' + base;
 }
 // remove trailing slash
 return base.replace(/\/$/, '')
}

这段代码的作用是设置路由的base路径,如果有兴趣一路跟踪的话会发现这个base参数是由实例化VueRouter时候传入的options.base

再看代码,他会判断如果base是空的,那么就会给一个默认值:

如果实在浏览器(非服务器环境)下执行,那么会调用document.querySelector('base')来尝试获取<base href='' />标签中href属性的值;

在我们实际的场景中,这里得到一个跨域的绝对地址,然后紧接着

if (base.charAt(0) !== '/') {
  base = '/' + base;
 }

当url第一个字符不是/的时候加上/,这里非常明显是一个BUG

我的是绝对地址http://static.com第一个字符当然不是/,所以才会由之前的http://api.com/http:/static.com/test这样的网址

修改

if(/^([a-z]+:)?\/\//i.test(base)){

}else if (base.charAt(0) !== '/') {
 base = '/' + base;
}

为了尽量少破坏源码,这里加了一个空的if,当url是由协议开始时,认为是绝对路径。

* 绝对路径还有一种形式是 //static.com

测试

经过第一次修改,再次访问页面依然有问题,访问的页面依然是http://api.com/http:/static.com/test

继续分析

再次跟踪源码后发现

[vue-router.esm.js][source]

//2006行~2016行
 HTML5History.prototype.push = function push (location, onComplete, onAbort) {
  var this$1 = this;

  var ref = this;
  var fromRoute = ref.current;
  this.transitionTo(location, function (route) {
   pushState(cleanPath(this$1.base + route.fullPath));
   handleScroll(this$1.router, route, fromRoute, false);
   onComplete && onComplete(route);
  }, onAbort);
 };
//561行~563行
function cleanPath (path) {
 return path.replace(/\/\//g, '/')
}

在发生pushState之前,他还会对url再次进行处理cleanPath

而这里的处理更简单,更粗暴,问题也更大。

他直接将2个斜杠//替换为1个斜杠/,话说如果连续3个斜杠怎么办?

所以在处理http://static.com/test地址的时候,其实会被处理成http:/static.com/test 又变成相对路径了...

继续修改

function cleanPath (path) {
  var ishttp = /^([a-z]+:)?\/\//i.exec(path);
  var http = Array.isArray(ishttp) ? ishttp[0] : '';
  return http + path.substr(http.length).replace(/\/{2,}/g, '/');
}

如果是协议开始,则排除协议内容之后,将2个或2个以上连续在一起的斜杠替换为1个斜杠。

** 完成提交pull

https://github.com/vuejs/vue-router/pull/1353/files

话说vue-router的url处理比起Url.js来说真的是太粗暴了...

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 嵌套的函数(作用域链)
Mar 15 Javascript
ExtJS TabPanel beforeremove beforeclose使用说明
Mar 31 Javascript
jquery插件制作 提示框插件实现代码
Aug 17 Javascript
前端开发过程中浏览器版本的两种判定方法
Oct 30 Javascript
页面定时刷新(1秒刷新一次)
Nov 22 Javascript
jquery动态改变form属性提交表单
Jun 03 Javascript
JavaScript中setUTCFullYear()方法的使用简介
Jun 12 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
Aug 31 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
Feb 15 Javascript
小发现之浅谈location.search与location.hash的问题
Jun 23 Javascript
Vue编写可显示周和月模式的日历 Vue自定义日历内容的显示
Jun 26 Javascript
vue实现简单图片上传
Jun 30 Javascript
JavaScript使用readAsDataUrl方法预览图片
May 10 #Javascript
Bootstrap table使用方法总结
May 10 #Javascript
将angular-ui的分页组件封装成指令的方法详解
May 10 #Javascript
vue-axios使用详解
May 10 #Javascript
详解axios在vue中的简单配置与使用
May 10 #Javascript
jQuery+PHP+Mysql实现抽奖程序
Apr 12 #jQuery
JavaScript实现form表单的多文件上传
Mar 27 #Javascript
You might like
linux下安装php的memcached客户端
2014/08/03 PHP
Parse正式发布开源PHP SDK
2014/08/11 PHP
PHP实现返回JSON和XML的类分享
2015/01/28 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
WordPress中使主题支持小工具以及添加插件启用函数
2015/12/22 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
js arguments.callee的应用代码
2009/05/07 Javascript
JQuery从头学起第二讲
2010/07/04 Javascript
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
js倒计时简单实现代码
2016/08/11 Javascript
JS获取年月日时分秒的方法分析
2016/11/28 Javascript
Bootstrap表单使用方法详解
2017/02/17 Javascript
Express之get,pos请求参数的获取
2017/05/02 Javascript
react-native之ART绘图方法详解
2017/08/08 Javascript
vue.js分页中单击页码更换页面内容的方法(配合spring springmvc)
2018/02/10 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
2019/04/14 Javascript
[02:02]2018DOTA2亚洲邀请赛Mineski赛前采访
2018/04/04 DOTA
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
2015/02/04 Python
编写简单的Python程序来判断文本的语种
2015/04/07 Python
Python可变参数函数用法实例
2015/07/07 Python
用matplotlib画等高线图详解
2017/12/14 Python
python实现mysql的读写分离及负载均衡
2018/02/04 Python
python 数字类型和字符串类型的相互转换实例
2018/07/17 Python
五种Python转义表示法
2020/11/27 Python
pycharm 关闭search everywhere的解决操作
2021/01/15 Python
CSS3 transforms应用于背景图像的解决方法
2019/04/16 HTML / CSS
幼儿教师个人求职信范文
2013/09/21 职场文书
夜大毕业生自我评价分享
2013/11/10 职场文书
采购文员岗位职责
2013/11/20 职场文书
四风问题自查报告剖析材料
2014/02/08 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
应届大专生求职信
2014/06/26 职场文书
个人年底工作总结
2015/03/10 职场文书