第一篇博客,多多指教。
多文件的上傳問題
首先File Transfer 插件,可以download、upload 文件,上傳單文件是沒有問題,也就是說上傳頭像的功能可以用,但是多文件就派不上用場了。
這里介紹的核心方法是window.resolveLocalFileSystemURL(),這是File Transfer 插件提供的一個(gè)方法,可以根據(jù)拍照、錄視頻拿到的File Path,讀取文件流,將文件流解析為二進(jìn)制Blob對象,然后拼接到Form Data對象上,最后上傳服務(wù)器。
下面我一步一步說,從拍照到上傳,代碼貼到下面:
//打開相機(jī)
$scope.openMedia = function (type) {
// myPopup.close();
$scope.popupShow = false;
if (type === 2) {
service.promiseProxy(function (promise) {
service.videoCapture(promise);
}, function (videoData) {
var filePath = videoData[0].fullPath;
var fileObj = {
filePath: filePath,
mediaType: 1
};
$scope.mediaDataArr.push(fileObj);
});
} else {
service.promiseProxy(function (promise) {
service.openCamera(type, promise);
}, function (filePath) {
var fileObj = {
filePath: filePath,
mediaType: 0
};
$scope.mediaDataArr.push(fileObj);
});
}
};
這里把多個(gè)filePath組裝為object,分別有filePath和mediaType兩個(gè)屬性,放到mediaDataArr這個(gè)數(shù)組里。
var tempArr = $scope.mediaDataArr,
len = $scope.mediaDataArr.length,
filePathArr = [];
var fd = new FormData();
// console.log('視頻路徑: ' + tempArr[0].filePath);
var idx = 0;
var platform = service.currentPlatform();
tempArr.forEach(function (value, index) {
if (platform === 'ios' && value.mediaType === 1) {
value.filePath = "file://" + value.filePath;
}
window.resolveLocalFileSystemURL(value.filePath, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
var the_file;
if (value.mediaType === 0) {
the_file = new Blob([e.target.result], { type: "image/jpeg" });
fd.append("files", the_file, 'img.jpeg');
// console.log('這是個(gè)圖片');
} else if (value.mediaType === 1) {
the_file = new Blob([new Uint8Array(e.target.result)], { type: "video/mp4" });
fd.append("files", the_file, 'video.mp4');
// console.log('這是個(gè)視頻');
}
idx++; //計(jì)數(shù)器,解決異步問題
if (idx === tempArr.length) {
//此處拼接到表單fd.append();
service.reportSubmit(fd, promise);
}
};
reader.readAsArrayBuffer(file);
}, function (e) {
});
}, function (e) {
});
});
注意兩點(diǎn):其一,圖片和視頻解析為Blob對象的方式稍有不同;其二,文件讀取的過程是異步的,每一個(gè)文件讀取完都會(huì)觸發(fā)reader.onloadend()方法,那么如何在所有文件全部讀取完,然后統(tǒng)一拼接到formData對象上,最后上傳到指定serverUrl。我們在reader.onloadend()方法里放了一個(gè)計(jì)數(shù)器,當(dāng)idx === tempArr.length 時(shí),表示所有文件全部讀取完畢,我們就可以執(zhí)行上傳操作啦!