記錄jQuery File Upload 的一些使用方法

插件的基本信息

  • 插件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登錄票據,這樣也能有效的保證只有登錄用戶才能上傳文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章