关于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 相关文章推荐
jquery 学习之二 属性(html()与html(val))
Nov 25 Javascript
JS获取随机数函数可自定义最小值最大值
May 08 Javascript
jQuery扁平化风格下拉框美化插件FancySelect使用指南
Feb 10 Javascript
强大Vue.js组件浅析
Sep 12 Javascript
JavaScript实现使用Canvas绘制图形的基本教程
Oct 27 Javascript
jQuery 插件实现随机自由弹跳气泡样式
Jan 12 Javascript
jQuery Chosen通用初始化
Mar 07 Javascript
JavaScript之json_动力节点Java学院整理
Jun 29 Javascript
浅谈Vuex的状态管理(全家桶)
Nov 04 Javascript
vue单页应用在页面刷新时保留状态数据的方法
Sep 21 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
Sep 29 Javascript
javascript+Canvas实现画板功能
Jun 23 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
php缓存技术介绍
2006/11/25 PHP
如何用PHP实现插入排序?
2013/04/10 PHP
php中如何判断一个网页请求是ajax请求还是普通请求
2013/08/10 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
JQuery团队打造的javascript单元测试工具QUnit介绍
2010/02/26 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
jQuery创建自己的插件(自定义插件)的方法
2010/06/10 Javascript
select标记美化--JS式插件、后期加载
2013/04/01 Javascript
javascript同页面多次调用弹出层具体实例代码
2013/08/16 Javascript
jquery实现可拖动DIV自定义保存到数据的实例
2013/11/20 Javascript
jquery库文件略庞大用纯js替换jquery的方法
2014/08/12 Javascript
node.js中的fs.readFile方法使用说明
2014/12/15 Javascript
使用Chart.js图表库制作漂亮的响应式表单
2015/10/28 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
2016/05/09 Javascript
AngularJS中$watch和$timeout的使用示例
2016/09/20 Javascript
JavaScript中this的用法实例分析
2016/12/19 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
javaScript代码飘红报错看不懂?读完这篇文章再试试
2020/08/19 Javascript
[53:21]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-CDEC
2014/05/22 DOTA
Django框架中方法的访问和查找
2015/07/15 Python
python如何实现反向迭代
2018/03/20 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
python3处理word文档实例分析
2020/12/01 Python
实习生自荐信范文分享
2013/11/27 职场文书
大学生职业生涯规划范文
2013/12/31 职场文书
英语教师岗位职责
2014/03/16 职场文书
党风廉设责任书
2014/04/16 职场文书
2014年底个人工作总结
2015/03/10 职场文书
2015个人简历自我评价语
2015/03/11 职场文书
2015年财务部工作总结
2015/04/10 职场文书
国富论读书笔记
2015/06/26 职场文书
百日宴上的祝酒词
2015/08/10 职场文书
公司团队口号霸气押韵
2015/12/24 职场文书
企业团队精神心得体会
2016/01/19 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS
Python 详解通过Scrapy框架实现爬取百度新冠疫情数据流程
2021/11/11 Python