本文已参与「新人创作礼」活动,一起开启掘金创作之路。
接到个需求,需要js自己去取本地的文件并上传,要求不使用input标签
实现思路,先使用了ie的ActiveXObject方法,这里先需要把ie浏览器的安全设置都设为最低,再把项目地址拉到信任地址里。
var fso = new ActiveXObject("Scripting.FileSystemObject");
ar f1 = fso.GetFile("c:\xxx.txt");
打印发现获取到的文件是空,如果调用readTextFile方法,只能读取文本文档,对于其他格式的无能为力,于是又换了个思路
var fso = new ActiveXObject("ADODB.Stream");
stream.type = 1;
stream.Open();
stream.LoadFromFile(本地文件地址);
打印也是空。。吐了 既然ie的方法看起来不行,那就换一种,本项目使用的vue-cli2 使用axios请求本地文件,并转换为流!
data(){
return {
url:require('C:/xxx/mp4')
}
},
methods:{
read(){
axios.get(this.url,{
//这行不加必不成功,会引发文件损坏
responseType:'blob;
}).then(res=>{
console.log(res.data)
//正常应该是blob类型
console.log(Object.prototype.toString.call(res.data))
let blob = new Blob([res.data])
//下载实验一下,这是ie的下载方法,chrome可以用a标签,可以看我之前的文章
window.navigator.msSaveOrOpenBlob(blob,'name.mp4')
//下载成功说明文件获取没问题,调用上传方法
this.upload(blob);
})
}
}
其实还有其他方法,比如node服务里面的fs模块,或者结合cordova插件,但需求不允许,就没再尝试,浏览器读取本地文件这种需求不常见,欢迎大神讨论。
================================================ 更新,axios方法在本地可以实现,但是部署到服务器又不行了,还是需要使用ie的ActiveXObject,这次可以在ie实现了。
<button onClick = 'active()'>上传</button>
var xml= new ActiveXObject("Msxml2.XMLHTTP.6.0");
xml.onreadystatechange=function(){
if(xml.readyState<4) return;
var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
var tmpNode = xml_dom.createElement("tmpNode");
tmpNode.dataType = "bin.base64";
tmpNode.nodeTypedValue = xml.responseBody;
var base64str=tmpNode.text.replace(/\n/g,"");
var blob = base64ToBlob(base64str)
//上传方法
upload(blob);
}
function base64ToBlob(base64){
var bstr = atob(base64),
n = bstr.length,
u8Arr = new Uint8Array(n);
while(n--){
u8Arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8Arr])
}
function active() {
x.open("get","C:\\temp\\abc.wmv",true);
x.send("");
}