JS异步上传文件

文件上传在网页应用中应该是一个很常用的功能,但是我是第一次做,所以也是网上找资料了,看了如阮一峰老师的《文件上传的渐进式增强》对文件上传有了大概的了解,结合自己的知识改写了一个文件上传工具共享给大家,包含了我在过程中遇到的坑~。


先上图

上代码

myUpload(option) {

va rfd =newFormData(),

xhr =newXMLHttpRequest(),

input,per;

input =document.createElement('input');

input.setAttribute('id','myUploadInput');

input.setAttribute('type','file');

input.setAttribute('name','files');

// input.setAttribute('accept','image/*')

document.body.appendChild(input);

input.style.display='none';

使用FormData仿真fram表结构,创建input按钮来上传文件,为了避免重复重复创建input标签修改代码如下

myUpload(option) {

varfd =newFormData(),

xhr =newXMLHttpRequest(),

input,loaded,total,per;

if(document.getElementById('myUploadInput')){

input =document.getElementById('myUploadInput');

}else{

input =document.createElement('input');

input.setAttribute('id','myUploadInput');

input.setAttribute('type','file');

input.setAttribute('name','files');

// input.setAttribute('accept','image/*')

document.body.appendChild(input);

input.style.display='none';

}

在上边代码中有一行被注释的代码

// input.setAttribute('accept','image/*')

我想控制只能上传图片,但带来一个很大延迟反应是,点击了图片上传功能后过了3,4秒才弹出文件上传框,而且用户还能修改文件上传格式,这个方法行不通。所以最后通过js代码控制了文件上传格式,看如下代码

varfileType = ['jpg','png','bmp','jpeg'];

vartype = input.value.split('.').pop();

if(fileType.indexOf(type.toLocaleLowerCase()) == -1) {

alert('只支持(jpg,png,bmp,jpeg)后缀文件');

}

通过input的onchange事件响应文件上传

input.click();

input.onchange=function() {

if(!input.value) {

return;

}

varfileType = ['jpg','png','bmp','jpeg'];

vartype = input.value.split('.').pop();

if(fileType.indexOf(type.toLocaleLowerCase()) == -1) {

alert('只支持(jpg,png,bmp,jpeg)后缀文件');

}

if(option.maxSize&& input.files[0].size> option.maxSize*1024*1024) {

alert('请上传小于'+option.maxSize+'M的文件');

return;

}

if(option.beforeSendinstanceofFunction) {

if(option.beforeSend(input) ===false) {

return false;

}

}

fd.append('files',input.files[0]);

xhr.onreadystatechange=function() {

if(xhr.status==200) {

if(xhr.readyState==4) {

if(option.callbackinstanceofFunction) {

option.callback(xhr.responseText);

}

}

}else if(xhr.status!=200){

alert('上传失败')

}

}

xhr.upload.onprogress=function(event) {

varpre =Math.floor(100* event.loaded / event.total);

if(option.uploadinginstanceofFunction) {

option.uploading(pre);

}

console.log('onprogress loaded'+ event.loaded );

console.log('onprogress total'+ event.total);

console.log('onprogress'+ pre);

}

xhr.open('post',option.url);

xhr.send(fd);

}

}

上边代码有几个坑,

兼容性问题

其一,FormData不支持IE11以下版本的浏览器(大家按需求引用)

其二,在IE浏览器中会出现,文件上传会出现点一次点击没有上传文件,再次点击才上传文件。出现的原因可能是input呼出文件上传框中断了input onchange事件。代码修改如下

input.onchange=function() {

if(!input.value) {

return;

}

varfileType = ['jpg','png','bmp','jpeg'];

vartype = input.value.split('.').pop();

if(fileType.indexOf(type.toLocaleLowerCase()) == -1) {

alert('只支持(jpg,png,bmp,jpeg)后缀文件');

}

if(option.maxSize&& input.files[0].size> option.maxSize*1024*1024) {

alert('请上传小于'+option.maxSize+'M的文件');

return;

}

if(option.beforeSendinstanceofFunction) {

if(option.beforeSend(input) ===false) {

return false;

}

}

fd.append('files',input.files[0]);

xhr.onreadystatechange=function() {

if(xhr.status==200) {

if(xhr.readyState==4) {

if(option.callbackinstanceofFunction) {

option.callback(xhr.responseText);

}

}

}else if(xhr.status!=200){

alert('上传失败')

}

}

xhr.upload.onprogress=function(event) {

varpre =Math.floor(100* event.loaded / event.total);

if(option.uploadinginstanceofFunction) {

option.uploading(pre);

}

console.log('onprogress loaded'+ event.loaded );

console.log('onprogress total'+ event.total);

console.log('onprogress'+ pre);

}

xhr.open('post',option.url);

xhr.send(fd);

}

input.click();

}

此时还有一个问题是每次上传文件都会有alert提示alert('上传失败')

else if(xhr.status!=200&& xhr.readyState==4){

alert('上传失败')

}

/*

0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。

1 (载入):已经调用open() 方法,但尚未发送请求。

2 (载入完成): 请求已经发送完成。

3 (交互):可以接收到部分响应数据。

4 (完成):已经接收到了全部数据,并且连接已经关闭。

* */

 方法的调用的调用

在目标文件中申明 var uploadTool = requilre('./uploadTool');

uploadTo0l.myUpload({

url:文件上传路径',

maxSize:2,

beforeSend:function(file) {

console.log('beforeSendLogo'+ file);

},

callback:function(res) {

vardata =JSON.parse(res);

上传回调

}

},

uploading:function(pre) {

console.log('logo'+ pre);

上传进度

},

});

代码写完了,在IE11中,chrom,火狐,360都可以用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • Ajax和XMLHttpRequest 我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是...
    changxiaonan阅读 2,229评论 0 2
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,058评论 1 10
  • H5 meta详解 viewport width:控制 viewport 的大小,可以指定的一个值,如果 600,...
    FConfidence阅读 811评论 0 3
  • 一、老版本的XMLHttpRequest对象及用法 首先,新建一个XMLHttpRequest的实例。var xh...
    飞鱼_JS阅读 554评论 0 0
  • 原谅时光,记住美好, 删繁就简,定格岁月的片段, 任生命的潮水涌动,我心自安然。 ~~~~~~~~~~~~~写在本...
    诗小蛮5786400阅读 284评论 0 3