標籤:nod gre 一個 message func 轉換 rest 伺服器 檔案的
HTML5定義了 FileReader 作為檔案 API 的重要成員用於讀取檔案,根據 W3C 的定義,FileReader介面提供了讀取檔案的方法和包含讀取結果的事件模型。
FileReader的執行個體擁有 4 個方法,其中 3 個用以讀取檔案,另一個用來中斷讀取。下面的表格列出了這些方法以及他們的參數和功能,需要注意的是 ,無論讀取成功或失敗,方法並不會返回讀取結果,這一結果儲存在 result 屬性中。
方法名 |
參數 |
描述 |
abort |
none |
中斷讀取 |
readAsBinaryString |
file |
將檔案讀取為二進位碼 |
readAsDataURL |
file |
將檔案讀取為 DataURL |
readAsText |
file, [encoding] |
將檔案讀取為文本 |
readAsText:該方法有兩個參數,其中第二個參數是文本的編碼方式,預設值為 UTF-8。這個方法非常容易理解,將檔案以文本方式讀取,讀取的結果即是這個文字檔中的內容。
readAsBinaryString:該方法將檔案讀取為二進位字串,通常我們將它傳送到後端,後端可以通過這段字串隱藏檔。
readAsDataURL:這是例子程式中用到的方法,該方法將檔案讀取為一段以 data: 開頭的字串,這段字串的實質就是 Data URL,Data URL是一種將小檔案直接嵌入文檔的方案。這裡的小檔案通常是指映像與 html 等格式的檔案。
FileReader還包含了一套完整的事件模型,用於捕獲讀取檔案時的狀態,下面這個表格歸納了這些事件。
事件 |
描述 |
onabort |
中斷時觸發 |
onerror |
出錯時觸發 |
onload |
檔案讀取成功完成時觸發 |
onloadend |
讀取完成觸發,無論成功或失敗 |
onloadstart |
讀取開始時觸發 |
onprogress |
讀取中 |
檔案一旦開始讀取,無論成功或失敗,執行個體的 result 屬性都會被填充。如果讀取失敗,則 result 的值為 null ,否則即是讀取的結果,絕大多數的程式都會在成功讀取檔案的時候,抓取這個值。
瞭解了H5提供的 FileReader 後,我們就使用 FileReader 來實現同事選擇多張圖片並上傳。
首先,在 HTML 加入一個file表單,並設定其為 multiple(瀏覽器在對multiple、disabled、checked、selected等這類屬性進行解析時,只要這些屬性存在,預設的就會被解析成true,甭管你設定的是disabled=true
或者disabled=false
亦或是disabled=""
,如果不想這些屬性起作用,唯有用js來remove掉這些屬性,除非你不設定這些屬性。),並設定accept="image/*"
用以只能選擇圖片類型的檔案,代碼如下:
<input type="file" accept="image/*" name="upload" id="upload" multiple><input type="hidden" id="hiddenImgUrl" /> <!--設定這個隱藏欄位是為了便於存放上傳至伺服器後返回的圖片地址-->
//圖片上傳var file = { upload: function (e) { var self = this; var files = e.target.files; var type = files[0].type.split(‘/‘)[0]; if (type != ‘image‘) { alertMsg(‘請上傳圖片‘); return; } //var size = Math.floor(file.size / 1024 / 1024); //if (size > 3) { // alert(‘圖片大小不得超過3M‘); // return; //}; for (var i = 0; i < files.length; i++) { var reader = new FileReader(); reader.readAsDataURL(files[i]); reader.onloadstart = function () { //用以在上傳前加入一些事件或效果,如載入中...的動畫效果 }; reader.onloadend = function (e) { var dataURL = this.result; var imaged = new Image(); imaged.src = dataURL; imaged.onload = function () { //利用canvas對圖片進行壓縮 var canvas = document.createElement(‘canvas‘); var ctx = canvas.getContext(‘2d‘); var w = 0; var h = 0; if (this.width > this.height) { h = 1000; var scale = this.width / this.height; h = h > this.height ? this.height : h; w = h * scale; } else { w = 1000; var scale = this.width / this.height; w = w > this.width ? this.width : w h = w / scale; } var anw = document.createAttribute("width"); var anh = document.createAttribute("height"); if (this.width > this.height) { anw.value = h; anh.value = w; } else { anw.value = w; anh.value = h; } canvas.setAttributeNode(anw); canvas.setAttributeNode(anh); if (this.width > this.height) { ctx.translate(h, 0); ctx.rotate(90 * Math.PI / 180) ctx.drawImage(this, 0, 0, w, h); ctx.restore(); } else { ctx.drawImage(this, 0, 0, w, h); } dataURL = canvas.toDataURL(‘image/jpeg‘); //回呼函數用以向資料庫提交資料 self.callback(dataURL); }; }; } }, event: function () { $("#upload").change(function (e) { file.upload(e); }); }, callback: function (dataURL) { $.ajaxSettings.async = false; //這裡必須將ajax的非同步改為同步才可以把返回並儲存在隱藏欄位中的圖片地址取出同時加在地址欄中作為參數一併傳入下一個頁面,這樣做的目的是因為返回的圖片地址不是一個json數組,而是單個的json字串,所以只能將返回的圖片地址json字串拼接在一起作為參數傳到下一個頁面 $.post(url, dataURL, function (res) { //將base64圖片流的圖片通過後台轉換成普通的圖片路徑並上傳至伺服器 var imgUrl = $("#hiddenImgUrl").val(); if (res.success) { $(".loading").hide(); if (imgUrl != "") { $("#hiddenImgUrl").val(imgUrl + "|" + res.imgUrl); //中間加一個 | 是為了到下一個頁面便於將傳過去的圖片地址參數轉換為數組 } else { $("#hiddenImgUrl").val(res.imgUrl); } var imgUrl = $("#hiddenImgUrl").val(); window.location.href = "apply.html?imgUrl=" + imgUrl; } else { alert(res.message); } }, "json"); }, init: function () { this.event(); }}file.init();
由於在通過post向伺服器上傳時採用了同步的方式,所以我在寫項目的過程中,老是無法實現載入中的動畫效果,並且把載入中的動畫效果放在 reader.onloadstart
方法中依舊不起作用,最後只能放在了$("#upload").change(function (e) {})
方法中,代碼如下:
event: function () { $("#upload").change(function (e) { $(".loading").show(); file.upload(e); }); }
以上是同時上傳多張圖片並將圖片傳入下一個頁面繼續進行後續操作,那麼如何在同時上傳完多張圖片後在本頁再預覽這些圖片呢?其實方法也是很簡單的,上邊callback函數裡邊的$.post的傳回值裡就包含了上傳至伺服器後的圖片路徑,將這些路徑賦給img標籤的src,然後再插入到頁面中就OK了,代碼如下:
callback: function (dataURL) { $.post(url, dataURL, function (res) { //將base64圖片流的圖片通過後台轉換成普通的圖片路徑並上傳至伺服器 if (res.success) { $(".loading").hide(); var result = ‘<div class="result"><img src="‘+res.imgUrl+‘" /></div>‘; var div = document.createElement(‘div‘); div.innerHTML = result; document.body.appendChild(div); } else { alert(res.message); } }, "json"); }
以上在預覽圖片時由於不需要跳轉,不需要傳入返回的所有圖片的路徑作為參數,所以也就不需要將ajax的非同步設定為同步了。
js 移動端 多圖上傳 預覽 傳給後端