记录jQuery File Upload 的一些使用方法

叶冥夜
2023-12-01

插件的基本信息

  • 插件demo
    https://blueimp.github.com/jQuery-File-Upload/
  • 插件配置
    官方文档:https://github.com/blueimp/jQuery-File-Upload/wiki/Setup
  • 选项
    https://github.com/blueimp/jQuery-File-Upload/wiki/Options

基本的使用示例

<script> 
	var $form = null;
   	$(function () {
         $form = $('#fileupload').fileupload({
            dataType: 'json',
			/*xhrFields: {withCredentials: true},*/
			complete: function (e, data) {
			   //code for done uploading callback
			   console.log(e.responseJSON);
			}
        });
		
    });
	
    $('#fileupload').addClass('fileupload-processing');

</script>

<form id="fileupload" method="POST" enctype="multipart/form-data" data-url="http://remote.com/FileUpload/Upload">
    
</form>
//data-url 修改为要提交的跨域网站上传服务地址

关于分块上传 chunked upload

如果不采用分块上传,经常会遇到上传大文件失败的情况,比如IIS默认传输文件大小为30M,最大允许传输为2G。 就算启用IIS的最大值,过大的文件传输也是容易失败的。

分块上传总体来说还是比较繁琐,需要前后端一起配合,前端代码需要对文件进行切片、计算,后端代码还需要按照传输的文件,按照次序进行组装。

  • 前端设置
<script>
        var $form = null;
	var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
	var collection = {};

	$(function() {
		$('#fileupload').fileupload({
			dataType: 'json',
			maxChunkSize: 10000000,
			//分块上传
			// 上传完成后的执行逻辑
			done: function(e, data) {
				$.each(data.result.files,
				function(index, file) {
					$('<p/>').text(file.name).appendTo(document.body);
				});
			},
			complete: function(e, data) {
				//code for done uploading callback
				console.log(e.responseJSON);
			},
			beforeSend: function(xhr, data) {

				data.files.forEach(function(file) {
					xhr.setRequestHeader('X-File-Identifier', collection[file.name + file.size]);
				}

				);
			},
			// 上传过程中的回调函数
			progressall: function(e, data) {

				var progress = parseInt(data.loaded / data.total * 100, 10);
				$(".bar").text(progress + '%');
				$('#progress .bar').css('width', progress + '%');
			}
		}).bind('fileuploadadd',
		function(e, data) {
			//console.log("add");
			data.files.forEach(function(file) {

				spark = new SparkMD5.ArrayBuffer();
				chunkSize = 10000000; // read in chunks of 10MB

				fileid = "";

				frOnload = function(e) {
					spark.append(e.target.result); // append array buffer
					fileid = spark.end();

					//保存文件 hash代码
					collection[file.name + file.size] = fileid;
				}

				function loadFile() {
					var fileReader = new FileReader();
					fileReader.onload = frOnload;

					var start = 0,
					end = ((start + chunkSize) >= file.size) ? file.size: start + chunkSize;

					fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
				};
				loadFile();
			}

			);

		});

	});</script>

在配置jQuery File Upload 的时候只要配置参数maxChunkSize就可以切换到分块上传模式,由于后台只有一个上传接口,所以需要在一些特殊文件头来区分出是否分块上传。
其实jQuery File Upload 本身就包含新加的头
分块第一个
Content-Range:bytes 0-9999999/167780896
分块第二个
Content-Range:bytes 10000000-19999999/167780896
最有一个
bytes 160000000-167780895/167780896

可以根据上面的HTTP头信息获得分块的次序

后来我又在之前基础上配置了一个HTTP头X-File-Identifier,主要考虑用这个标识来唯一确认文件,也可以称之为文件的ID。在用户选择需要上传的文件时,也就是绑定在 add 事件上,采用SparkMD5计算文件的md5码。下面的方法就是对所有新选择的文件进行 md5编码计算。考虑到有的文件过大,比如4G大小的文件,计算md5编码就好久,所以最多也就读取10MB

data.files.forEach(function(file) {
	spark = new SparkMD5.ArrayBuffer();
	chunkSize = 10000000; // read 10MB
	fileid = "";
	frOnload = function(e) {
		spark.append(e.target.result); // append array buffer
		fileid = spark.end();
		collection[file.name + file.size] = fileid;
	}
	function loadFile() {
		var fileReader = new FileReader();
		fileReader.onload = frOnload;
		var start = 0,
		end = ((start + chunkSize) >= file.size) ? file.size: start + chunkSize;

		fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
	};
	loadFile();
});

为了方便上传后端后,能够识别文件的 唯一编码 (hash编码),需要在上传前在HTTP头信息中加入文件标识

data.files.forEach(function(file) {
	xhr.setRequestHeader('X-File-Identifier', collection[file.name + file.size]);
}

其实我觉得在这里还能添加一些验证的头信息,比如JWT登录票据,这样也能有效的保证只有登录用户才能上传文件。

 类似资料: