'Uncaught TypeError: this.xhr.upload.addEventListener is not a function'解决方案
解决方案
https://github.com/nuysoft/Mock/issues/127
我的解决方案是使用了greper提供的mockjs-x
问题描述
问题发生在Ant Design Vue Pro整合vue-simple-uploader时。
在选择上传文件后,控制台爆出了Uncaught TypeError: this.xhr.upload.addEventListener is not a function
错误。
发生时的状态
当前日期是2021/04/22。
Ant Design Vue Pro的commit记录为:2f663728bfdba21a9b89a4a4a5698ae802087b61
vue-simple-uploader的版本为:0.7.6
解决过程
解决方案一搜就搜到了:
Axios + mockjs: request.upload.addEventListener is not a function 的原因和解决办法
查错
不过还是没搞明白为什么出错,所以自己研究下。
压缩好的代码肯定看不懂。所以去node_modules
里找到vue-simple-uploader
,去看它的源代码。
源代码入口是index.js
。
可以看到,Uploader
组件是从./components/uploader.vue
导入的。而uploader.vue
又是导入了simple-uploader.js
。
去搜一下的话,发现就是vue-simple-uploader
作者的另一个项目。
3
有兴趣可以去看看。不过我们先直接把项目里用到vue-simple-uploader
的地方换成用源代码。
1 | // 原来的 |
再次上传文件,可以看到新的报错信息。
注意,变成了chunk.js,点进去看看:
原来是simple-uploader
里的一个chunk.js
出错了。
分析
其实已经很清楚了,MockJS会覆盖原生的XMLHttpRequest,所以chunk.js
里new的已经不是真正的XMLHttpRequest了。
而github的issue里较前面的解决方案也很清楚,无论是哪种方式都是在原型链上动手脚。
解决
第一次尝试
发现这个issue已经是2016年的了,目前Mockjs的版本为1.1.0,所以怀疑官方是不是已经解决了。
不过要注意,不知道什么原因,ant design pro vue使用的不是mock而是mockjs2。
Mockjs官方是nuysoft
的Mock,而mockjs2是sendya
的Mock,但是sendya
的是从nuysoft
的fork出来的,所以我们先尝试下换成mockjs试试。
答案是:
没有
第二次尝试
注意,这里是在第一次的尝试的基础上改,也就是说仍然用的mockjs而不是mockjs2。
github上说是在node_modules/mockjs/dist/mock.js
的8308行加上这句代码(跟之前博客里看到的一样):
1 | MockXMLHttpRequest.prototype.upload = xhr.upload; |
mockjs2的代码位置有一些变化。
不过这么做了以后,我的网页又不知道出了什么错,就一直在转圈的页面,控制台也不报错。应该是代码里出现了死循环了
既然不行,我就放弃了。而且其实就算能成功,我也不建议这么改。
因为node_modules是不会上传到git上的,这也就意味着别人如果下载了这个项目,npm install
后他也要去node_modules改,不太合适。
第三次尝试
既然官方没解决,就只能用其它人的了。
如上,npm i mockjs-x --save
后,替换所有mockjs成mockjs-x就好。
成功!!!
总结
问题的出现原因就是Mockjs覆盖了XMLHttpRequest导致其它使用XHR的代码出错。
个人很感谢greper,但说实话,使用mockjs-x这种方式也不太完美。单纯为了修复一个bug去使用另一个包。这样的话,mockjs官方有更新时就比较麻烦。
准备去寻找一下其它方式。。。