【JS】layui文件上传的中断处理

最近在做项目时,遇到一个需求是,上传文件过程中需要判断下是否已经存在该文件,如果存在,让用户来决定是否继续上传,这里边有两个注意点:

  1. 是否存在该文件,需要调取后台接口返回结果来,涉及一个异步问题;
  2. 是否继续上传,需要在上传回调函数中通过return false来阻止文件继续上传。

首先我的思路是在before回调中做中断,我采用的layui版本是v2.5.6,在更低的版本中需要改下upload.js源码,
y=function(){return "choose" === i ? l.choose && l.choose(g) : ((l.before && l.before(g)) === false ? '' : o.ie ? o.ie > 9 ? u() : c() : void u()) };
然后在页面中按部就班写下upload相关业务代码:

upload.render({

elem: '#chooseBtn',

url: 'XXXXX',

accept: 'file',

exts: 'xls|excel|xlsx',

headers: {

token: localStorage.getItem('token')

},

data: {},

before: function(obj) {

var flag = true;

layer.load(); //上传loading

files = obj.pushFile();

this.data = {

institution: $("#dropdownMenu1").val(),

handle_class: $("#handle_class").val(),

file_name: files[fileId].name

}

obj.preview(function (index, file, result) {

file_name = file.name

fileId = index;

$("#fileWrap").append('<li id="' + fileId + '"><span>' + file.name +

'上传中</span><i class="layui-icon layui-icon-close"></i></li>'

)

$.ajax({

url: 'mon/monitor/clean/checkUpload.json',

contentType: 'application/x-www-form-urlencoded',

type: 'post',

beforeSend: function (request) {

request.setRequestHeader('token', localStorage.getItem('token'));

},

data: {

institution: $("#dropdownMenu1").val(),

file_name: file.name

},

dataType: "json", //服务器返回数据的类型为json  

success: function (data) {

if (data.code == '100') {

$('#chooseBtn').css('display', 'none')

flag = true

} else {

if (data.code == '104') {

layer.confirm(data.msg + ',点击确定将替换原文件', {

title: '提示',

btn: ['取消', '确定']

},

function (index) {

//do something

delete files[fileId];

$("#fileWrap").find('li[id="' + fileId + '"]').remove();

layer.close(index);

flag = false

return false

},

function (index) {

flag = true

obj.upload(fileId, file)

$('#chooseBtn').css('display', 'none')

});

return false

} else {

flag = false

layer.msg(data.msg)

}

}

},

error: function (data) {

flag = false

console.error(data)

}

})

});

return flag

},

done: function (res, index, upload) {

console.log(res, index)

layer.closeAll('loading'); //关闭loading

},

error: function (index, upload) {

layer.closeAll('loading'); //关闭loading

delete files[index];

$("#fileWrap").find('li[id="' + index + '"]').remove();

$("#chooseBtn").css('display', 'inline-block')

}

});

这样做看似没有问题,但是实际上选完文件之后就立即上传了,而去重判断的接口甚至是文件已经上传成功了才返回了结果,在上传文件前的flag读取的其实还是初始值true,因此并没有阻止上传进程,后来又尝试将去重改为同步async:false,又将去重整个赋值给一个函数,最后在before中return这个函数,结果就是flag虽然变成了期望的值false,但是依然没有阻止上传进程...
多次尝试之后,灵机一动既然立即上传不行,那可以试试触发按钮上传,这样做的好处是,选择文件其实只执行了choose这个选择文件回调,当点击了设置的这个上传开关按钮之后才会执行before,done,error这些回调,因此最终的解决思路就是:

  1. 选择文件后立马做(choose回调中)去重判断,并保存判断的结果;
  2. 点击上传按钮后立马决定(拿着去重结果)是否继续上传

代码仅供参考

var files = null;

var fileId = '';

var file_name = '';

var flag = true;

var uploadInst = upload.render({

elem: '#chooseBtn',

url: 'XXX',

accept: 'file',

auto: false,

bindAction: '#startBtn',

exts: 'xls|excel|xlsx',

headers: {

token: localStorage.getItem('token')

},

data: {},

xhr: xhrOnProgress, //传入监听函数!important

choose: function(obj) {

$("#startBtn").css('display', 'inline-block')

files = obj.pushFile();

obj.preview(function (index, file, result) {

file_name = file.name

fileId = index;

$("#fileWrap").append('<li id="' + fileId + '"><span>' + file.name +'上传中</span><i class="layui-icon layui-icon-close"></i><div class="layui-progress layui-progress-big" lay-filter="progressBar'+fileId+'" lay-showPercent="yes"><div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div></div></li>')

element.render('progress', 'progressBar'+fileId);

$.ajax({

url: 'xxx',

contentType: 'application/x-www-form-urlencoded',

type: 'post',

async: false,

beforeSend: function (request) {

request.setRequestHeader('token', localStorage.getItem('token'));

},

data: {

institution: $("#dropdownMenu1").val(),

file_name: file.name

},

dataType: "json",

success: function (data) {

if (data.code == '100') {

$('#chooseBtn').css('display', 'none')

flag = true

} else {

if (data.code == '104') {

layer.confirm(data.msg + ',点击确定将替换原文件', {

title: '提示',

btn: ['取消', '确定']

},

function (index) {

//do something

delete files[fileId];

$("#fileWrap").find('li[id="' + fileId + '"]').remove();

layer.close(index);

flag = false

return false

},

function (index) {

flag = true

obj.upload(fileId, file)

$('#chooseBtn').css('display', 'none')

});

return false

} else {

flag = false

layer.msg(data.msg)

}

}

},

error: function (data) {

flag = false

console.error(data)

}

})

});

},

before: function (obj) {

layer.load(); //上传loading

console.log('this:', this)

this.data = {

institution: $("#dropdownMenu1").val(),

handle_class: $("#handle_class").val(),

file_name: files[fileId].name

}

return flag

},

progress: function(n, elem){

var percent = n + '%' //获取进度百分比

element.progress('progressBar'+fileId, percent); //可配合 layui 进度条元素使用

},

done: function (res, index, upload) {

console.log(res, index)

layer.closeAll('loading'); //关闭loading

if (files) {

delete files[index];

}

if (res.code == '100') {

fileSuccess = true

$("#fileWrap li span")[0].innerText = file_name

} else {

layer.msg(res.msg)

$("#fileWrap").find('li[id="' + fileId + '"]').remove();

fileSuccess = false

}

$("#startBtn").css('display', 'none');

$('#chooseBtn').css('display', 'inline-block');

},

error: function (index, upload) {

layer.closeAll('loading'); //关闭loading

delete files[index];

$("#fileWrap").find('li[id="' + index + '"]').remove();

$("#chooseBtn").css('display', 'inline-block')

}

});

$("#fileWrap").on('click', 'li i', function(e) {

var fileId = $(this).parent('li').attr("id");

delete files[fileId];

$(this).parent('li').remove();

$("#chooseBtn").css('display', 'inline-block')

});

页面如图:
【JS】layui文件上传的中断处理
点击上传开关后,点击确定之后还需才会上传,否则重新选择文件,再次触发choose回调,进行去重判断...
上传成功后隐藏了上传开关
【JS】layui文件上传的中断处理
再多一点废话:进度条
同样是在upload.js文件中需要在p.prototype.config中加上xhr,即
p.prototype.config={accept:"images",exts:"",auto:!0,bindAction:"",url:"",field:"file",acceptMime:"",method:"post",data:{},drag:!0,size:0,number:0,multiple:!1,xhr: function() {}}
然后创建进度条监听函数

var xhrOnProgress = function (fun) {

xhrOnProgress.onprogress = fun; //绑定监听

//使用闭包实现监听绑

return function () {

//通过$.ajaxSettings.xhr();获得XMLHttpRequest对象

var xhr = $.ajaxSettings.xhr();

//判断监听函数是否为函数

if (typeof xhrOnProgress.onprogress !== 'function')

return xhr;

//如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去

if (xhrOnProgress.onprogress && xhr.upload) {

xhr.upload.onprogress = xhrOnProgress.onprogress;

}

return xhr;

}

}

进度条在选择文件的预览方法已经追加了dom,但是在此必须激活一下,否则会出现的情况是进度条虽然动态变化了,但是上面的文字也就是百分数没有跟着变,因此需这行:
element.render('progress', 'progressBar'+fileId);
然后在progress回调中更新进度就好了
今天就分享这么多吧,有更好的方案一起讨论哟~~~

以上是 【JS】layui文件上传的中断处理 的全部内容, 来源链接: utcz.com/a/103353.html

回到顶部