JS、JQ实现图片上传,文件上传、带进度条上传的几种方法
1.原生ajax上传带进度条
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传 原生ajax上传</title>
<style type="text/css">
.container {
width: 200px;
height: 20px;
background-color: gray;
}
#progress {
height: 20px;
background-color: orange;
display: inline-block;
}
</style>
</head>
<body>
<form action="${pageContext.request.contextPath }/upload" enctype="multipart/form-data" method="post">
上传文件1: <input type="file" name="file1" id="file"><br />
<div class='container'>
<span id="progress"></span>
</div>
</form>
<br>
<button onclick="fileSelected()">文件信息</button><button onclick="uploadFile()">确认上传</button>
<div id="info">
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
</div>
<div id="result"></div>
<script>
function fileSelected() {
var file = document.getElementById('file').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
}
}
function uploadFile() {
var fd = new FormData();
fd.append("file", document.getElementById('file').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "${pageContext.request.contextPath }/upload");//修改成自己的接口
xhr.send(fd);
}
function uploadProgress(evt) {
if (evt.lengthComputable) {
var percent = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progress').innerHTML = percent.toFixed(2) + '%';
document.getElementById('progress').style.width = percent.toFixed(2) + '%';
}
else {
document.getElementById('progress').innerHTML = 'unable to compute';
}
}
function uploadComplete(evt) {
/* 服务器端返回响应时候触发event事件*/
document.getElementById('result').innerHTML = evt.target.responseText;
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
}
</script>
</body>
</html>
运行效果如果:
2.Jquery ajax上传带进度条
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传 jquery上传</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<style type="text/css">
.container {
width: 200px;
height: 20px;
background-color: gray;
}
#progress {
height: 20px;
background-color: orange;
display: inline-block;
}
</style>
</head>
<body>
<form action="${pageContext.request.contextPath }/upload" enctype="multipart/form-data" method="post">
上传文件1: <input type="file" name="file1"><br />
<div class='container'>
<span id="progress"></span>
</div>
</form>
<br>
<button onclick="upload()">确认上传</button>
<div id="info"></div>
<div id="result"></div>
<script>
var totalSize = 0;
//绑定所有type=file的元素的onchange事件的处理函数
$(':file').change(function () {
var file = this.files[0]; //假设file标签没打开multiple属性,那么只取第一个文件就行了
name = file.name;
size = file.size;
type = file.type;
url = window.URL.createObjectURL(file); //获取本地文件的url,如果是图片文件,可用于预览图片
totalSize += size;
$("#info").html("文件名:" + name + "<br>文件类型:" + type + "<br>文件大小:" + size + "<br>url: " + url);
});
function upload() {
//创建FormData对象,初始化为form表单中的数据。需要添加其他数据可使用formData.append("property", "value");
var formData = new FormData($('form')[0]);
//ajax异步上传
$.ajax({
url: "${pageContext.request.contextPath }/upload",
type: "POST",
data: formData,
xhr: function () { //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数
myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { //检查upload属性是否存在
//绑定progress事件的回调函数
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
}
return myXhr; //xhr对象返回给jQuery使用
},
success: function (result) {
$("#result").html(result);
},
contentType: false, //必须false才会自动加上正确的Content-Type
processData: false //必须false才会避开jQuery对 formdata 的默认处理
});
}
//上传进度回调函数:
function progressHandlingFunction(e) {
if (e.lengthComputable) {
$('#progress').attr({ value: e.loaded, max: e.total }); //更新数据到进度条
var percent = e.loaded / e.total * 100;
$('#progress').html(e.loaded + "/" + e.total + " bytes. " + percent.toFixed(2) + "%");
$('#progress').css('width', percent.toFixed(2) + "%");
}
}
</script>
</body>
</html>
3.图片上传
/** 自定义文件上传方式
* @param {[object]} $obj [传入对应的整体对象,最外层对象]
* @param {[string]} selector [传入对应的选择器class]
* @param {[function]} callback [回调函数]
*/
var selfUploadFile = function ($obj, selector, callback) {
var json = {
maxFileSize: 3000000, // 3 MB
maxFileCount: 3,
messages: {
acceptFileTypes: '图片格式不正确',
maxFileSize: '上传图片大小不超过3M',
maxFileCount: '上传图片个数不能超过三个',
}
}
$obj.find(selector).fileupload({
pasteZone: null,
url: "/common/upload/image", //文件上传地址,可以直接写在input的data-url属性内
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 3000000, // 3 MB
change: function(e, data) {
var bool = false;
/* 上传文件个数控制 */
if(data.files.length + $obj.find('.cover-img').find('img').length > json.maxFileCount) {
alert(json.messages.maxFileCount);
return false;
}
/* 上传文件大小控制 */
$.each(data.files, function (i, _) {
if(_.size > json.maxFileSize) {
bool = true;
return false;
}
});
if(bool) {
alert(json.messages.maxFileSize);
return false;
}
},
drop: function(e, data) {
},
done: function(e, result) {
callback(e, result);
if (result.result) {
var data = result.result;
if (data && data.status == 500) {
alert(data.msg);
return;
}
}
}
});
}
调用方法
_common.selfUploadFile($('.box'), '.upload', function (e, resault) {
var urlStr = resault.result.data.uri;
});
4.原生上传,动态绑定节点,form表单提交
/**
* 原生上传,动态绑定节点,form表单提交
* @param {[object]} $obj [传入对应的整体对象,最外层对象, 这个定义好后一定不能产生变动]
* @param {[string]} selector [传入对应的选择器class, input type=file 那个节点]
* @param {[function]} beforeSend [回调函数, 上传之前执行,提前校验,成功返回true,不成功返回false]
* @param {[function]} callback [回调函数]
*/
uploadFile: function ($obj, selector, beforeSend, callback) {
$obj.off('change.upFile').on('change.upFile', selector, function (e) {
$obj.find(selector).eq(0)
var fileList = e.originalEvent.target.files;
/* 上传之前进行校验 */
if(!beforeSend(e.originalEvent.target.files)) {return false};
$.each(fileList, function (i, f) {
if (/^image/.test(f.type)) {
var xhr = new XMLHttpRequest();
xhr.open("post", '/common/upload/image', true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}
//模拟数据
var fd = new FormData();
fd.append('file', f);
xhr.send(fd);
xhr.addEventListener('load', function (e) {
var r = JSON.parse(e.target.response);
if(r.errorCode == '200') {
callback('success', r);
/* 上传完成后清空input 不然同一个文件无法连续上传*/
$obj.find(selector).val('')
}
});
});
});
}
5.后端提供签证 前端上传文件到腾讯云cos (ps:需引入cos-js-sdk-v5.min.js或cos-js-sdk-v5.js)官方文档 https://cloud.tencent.com/document/product/436/11459
var Bucket = '';
var Region = 'ap-';
// 初始化实例
var cos = new COS({
getAuthorization: function (options, callback) {
var url = 'http://10.1.24.7:4005/getSign';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
try {
var data = JSON.parse(e.target.responseText).data;
} catch (e) {
}
callback({
// 后端返回 key 和secretid
TmpSecretId: data && data.tmpSecretId,
TmpSecretKey: data && data.tmpSecretKey,
XCosSecurityToken: data && data.sessionToken,
ExpiredTime: data.expiredTime,
});
};
xhr.send();
}
});
// 事件委托 点击上传图片
$("body").on('change', ".img-upload", (e)=>{
// console.log(e.target);
var file = e.target.files[0];
if (!file) return;
// $(".upload-box").append('<div class="img-box"><img src="' + "http://" + dataStr + '" alt=""><i class="icon-del"></i></div>')
// 分片上传文件
cos.sliceUploadFile({
Bucket: Bucket,
Region: Region,
Key: file.name,
Body: file,
onHashProgress: function (progressData) {
// console.log('校验中', JSON.stringify(progressData));
},
onProgress: function (progressData) {
// 上传进度
// console.log('上传中', JSON.stringify(progressData));
},
}, function (err, data) {
if (data.statusCode == 200) {
// 上传成功执行的回调(通常用来回显 可结合第一种方法控制回显图片大小)
$(".upload-box").append('<div class="img-box" data-url="' + data.Location + '"><img src="' + "http://" + data.Location + '" alt=""><i class="icon-del"></i></div>')
$(".upload-img-box .upload-box").find(".img-box").length == 4 ? $(".upload-box").find(".file").remove() : "";
}
// console.log(err, data);
});
});
// 点击上传word 文档
$("body").on('change', ".word-upload", (e)=>{
console.log(e.target);
var file = e.target.files[0];
if (!file) return;
// $(".upload-box").append('<div class="img-box"><img src="' + "http://" + dataStr + '" alt=""><i class="icon-del"></i></div>')
// 分片上传文件
cos.sliceUploadFile({
Bucket: Bucket,
Region: Region,
Key: file.name,
Body: file,
onHashProgress: function (progressData) {
// console.log('校验中', JSON.stringify(progressData));
},
onProgress: function (progressData) {
// console.log('上传中', JSON.stringify(progressData));
},
}, function (err, data) {
if (data.statusCode == 200) {
$(".upload-word-box").find(".word-name").text(document.getElementById("word-upload").files[0].name)
$(".upload-word-box").find(".word-name").data("url", data.Location)
}
// console.log(err, data);
});
});
ps:
借鉴了前辈的代码 感谢前辈们的无私分享 心存感恩 勿忘初心!