在利用vue作一些H5頁面時,或多或少會遇到有圖片上傳的操做,主要是運用html5裏面的input[type=file]來實現,傳遞到後端的數據是以二進制的格式傳遞,因此上傳圖片的請求與普通的請求稍微有點差別,具體體如今傳遞數據的格式是FormData,FormData是一個構造函數,具體用法連接以下:html
MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/FormDatavue
其次,因爲圖片是以二進制方式上傳,因此須要修改下請求頭的Content-Type類型爲「multipart/form-data」以支持二進制數據上傳。html5
在具體有如下幾部分的實現:node
一、頁面端,利用H5的input[type=file]表單,進行圖片上傳,accept屬性能夠設置接收文件的類型,具體有: .doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document
ios
1 <input class="ele-hidden" type="file" accept="image/*" size="30" 2 ref="getPhoto" @change="uploadAvatar('getPhoto')">
二、選擇圖片確認後會觸發元素change事件,在input對象中,存在file屬性,file是一個數組,數組裏面存儲的上傳文件的File對象,裏面包含上傳文件的大小(size)、類型(type)、更改時間(lastModifiedDate)等。具體文檔可參考:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/filecanvas
讀取圖片信息能夠藉助FileReader,解析成瀏覽器識別的格式,以實現圖片的預覽,FileReader構造函數文檔地址爲:https://developer.mozilla.org/en-US/docs/Web/API/FileReader/FileReader,axios
實例代碼主要是爲了解決移動端上傳圖片過大而進行了壓縮,壓縮後的圖片體積大概是壓縮前的十分之一,仍是很可觀的。後端
uploadAvatar(node) {//圖片上傳
let $node = this.$refs[node];
let file = $node.files[0];//獲取當前選擇的照片
let formData = new FormData();
let _this = this;
if(!file) return;
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
let img = new Image();
img.onload = function () {
img.src = e.target.result;
let data = compress(img);
let blob = dataURItoBlob(data);
formData.append("photo", blob);
_this.submitModify(formData); //上傳方法
}
};
}
圖片解析和壓縮方法:數組
1 export function compress(img) { 2 let canvas = document.createElement("canvas"); 3 let ctx = canvas.getContext("2d"); 4 let initSize = img.src.length; 5 let width = img.width; 6 let height = img.height; 7 canvas.width = width; 8 canvas.height = height; 9 // 鋪底色 10 ctx.fillStyle = "#fff"; 11 ctx.fillRect(0, 0, canvas.width, canvas.height); 12 ctx.drawImage(img, 0, 0, width, height); 13 14 //進行最小壓縮 15 let ndata = canvas.toDataURL("image/jpeg", 0.1); 16 return ndata; 17 } 18 19 export function dataURItoBlob(base64Data) { 20 var byteString; 21 if (base64Data.split(",")[0].indexOf("base64") >= 0) 22 byteString = atob(base64Data.split(",")[1]); 23 else byteString = unescape(base64Data.split(",")[1]); 24 var mimeString = base64Data 25 .split(",")[0] 26 .split(":")[1] 27 .split(";")[0]; 28 var ia = new Uint8Array(byteString.length); 29 for (var i = 0; i < byteString.length; i++) { 30 ia[i] = byteString.charCodeAt(i); 31 } 32 return new Blob([ia], { type: mimeString }); 33 }
三、更改請求頭content-type類型瀏覽器
1 this.$axios.defaults.headers.post['Content-Type'] = 'multipart/form-data;charset=UTF-8';