ionic 專案檔案下載總結
阿新 • • 發佈:2019-02-07
一、前景
最近專案中使用了檔案下載,避免再次掉坑於是寫篇總結!
二、外掛簡介
cordova專案的檔案下載一般會使用到cordova-plugin-file、cordova-plugin-file-transfer、cordova-plugin-file-opener2三個外掛。
cordova plugin add cordova-plugin-file
cordova plugin add cordova-plugin-file-transfer
cordova plugin add https://github.com/pwlin/cordova-plugin-file -opener2.git
三、初始化不同平臺下載目錄
// 下載目錄
var downloadPath;
/**
* 初始化app的下載目錄
*/
initDownloadDirectory: function () {
var deferred = $q.defer();
/**
* cordova.file.dataDirectory 不同平臺對應位置如下
* android:'data/data/<app-id>/files/'
* IOS:'/var/mobile/Applications/<UUID>/Library/NoCloud/'
*/
/**
* 因android平臺,apk型別的檔案放到cordova.file.dataDirectory下,將無法正常安裝
*/
if (ionic.Platform.isAndroid()) {
// 初始化android平臺的下載目錄
downloadPath = cordova.file.externalRootDirectory + SystemConstant('download_path') + "/";
this.createDir(cordova.file.externalRootDirectory, SystemConstant('download_path' ))
.then(function (success) {
downloadPath = success.nativeURL;
deferred.resolve(success);
}, function (error) {
console.log("[download] init android platform's download dir occurred error :" + angular.toJson(error));
deferred.reject(error);
});
} else {
// 初始化IOS平臺的下載目錄
downloadPath = cordova.file.documentsDirectory + SystemConstant('download_path') + "/";
this.createDir(cordova.file.documentsDirectory, SystemConstant('download_path'))
.then(function (success) {
downloadPath = success.nativeURL;
console.log(success.nativeURL);
deferred.resolve(success);
}, function (error) {
console.log("[download] init IOS platform's download dir occurred error :" + angular.toJson(error));
deferred.reject(error);
});
}
}
/**
* 建立目錄
* @param path 目錄
* @param directory 目錄名稱
*/
createDir: function (path, directory) {
var deferred = $q.defer();
$cordovaFile.createDir(path, directory, false)
.then(function (success) {
deferred.resolve(success);
}, function (error) {
console.log("[download] create dir occurred error :" + angular.toJson(error));
deferred.reject(error);
});
return deferred.promise;
}
四、Android和IOS檔案系統對比
五、檔案下載
坑一:直接從伺服器返回的檔案流下載沒問題,但是,如果伺服器返回的為FTP的檔案流就存在下載後的檔案全是亂碼
解決:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding': 'gzip,deflate,sdch',
'accept-language': 'zh-CN,zh;q=0.8,en;q=0.6'
};
坑二: 同一檔案Android平臺可以下載,IOS平臺報錯(原因:檔名稱存在中文)
{
"code":1,
"target":null,
"http_status":201,
"body":"Could not create target file"
}
解決:
if (ionic.Platform.isIOS()) {
fileName = encodeURI(fileName);
}
下載完整程式碼如下:
/**
* 檔案下載
* @param url 資源定位
* @param targetPath 檔案儲存位置
* @param fileName 檔名稱
* @param isOpen 下載完成後是否開啟
* @returns {Promise}
*/
download: function (url, targetPath, fileName, isOpen) {
var deferred = $q.defer();
var trustAllHosts = true;
// 選項
var options = {};
//新增headers資訊
var headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding': 'gzip,deflate,sdch',
'accept-language': 'zh-CN,zh;q=0.8,en;q=0.6'
};
options.headers = headers;
$ionicLoading.show({template: "已經下載0%"});
$cordovaFileTransfer.download(url, targetPath, options, trustAllHosts)
.then(function (success) {
$ionicLoading.hide();
if (isOpen) {
// 檔案型別
var fileType = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length);
//開啟下載檔案
$cordovaFileOpener2.open(targetPath, MIME_MapTable(fileType))
.then(function (success) {
deferred.resolve(success);
}, function (error) {
console.log("[download] open file occurred error :" + angular.toJson(error));
deferred.reject({message: FileConstant('FILE_OPEN_FAIL')});
});
} else {
deferred.resolve(success);
}
}, function (error) {
$ionicLoading.hide();
console.log("[download] download file occurred error :" + angular.toJson(error));
deferred.reject({message: FileConstant('DOWNLOAD_FAIL')});
}, function (progress) {
$timeout(function () {
var downloadProgress = (progress.loaded / progress.total) * 100;
$ionicLoading.show({template: "已經下載" + Math.floor(downloadProgress) + "%"});
if (downloadProgress > 99) {
$ionicLoading.hide();
}
});
});
return deferred.promise;
}
/**
* 附件下載
* @param url 資源定位
* @param fileName 檔名
* @returns {Promise}
*/
downloadAttachment: function (url, fileName) {
var deferred = $q.defer();
url = encodeURI(url);
// 儲存路徑
var targetPath = downloadPath;
// IOS 平臺,如果檔名稱存在中文時需要轉碼
if (ionic.Platform.isIOS()) {
targetPath += encodeURI(fileName);
} else {
targetPath += fileName;
}
this.download(url, targetPath, fileName, true)
.then(function (success) {
deferred.resolve(success);
}, function (error) {
deferred.reject(error);
});
return deferred.promise;
}
/**
* MIME 資源型別
*/
.constant('MIME_MapTable', function (key) {
return {
"3gp": "video/3gpp",
"apk": "application/vnd.android.package-archive",
"asf": "video/x-ms-asf",
"avi": "video/x-msvideo",
"bin": "application/octet-stream",
"bmp": "image/bmp",
"c": "text/plain",
"class": "application/octet-stream",
"conf": "text/plain",
"cpp": "text/plain",
"exe": "application/octet-stream",
"gif": "image/gif",
"gtar": "application/x-gtar",
"gz": "application/x-gzip",
"h": "text/plain",
"htm": "text/html",
"html": "text/html",
"jar": "application/java-archive",
"java": "text/plain",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"js": "application/x-javascript",
"log": "text/plain",
"m3u": "audio/x-mpegurl",
"m4a": "audio/mp4a-latm",
"m4b": "audio/mp4a-latm",
"m4p": "audio/mp4a-latm",
"m4u": "video/vnd.mpegurl",
"m4v": "video/x-m4v",
"mov": "video/quicktime",
"mp2": "audio/x-mpeg",
"mp3": "audio/x-mpeg",
"mp4": "video/mp4",
"mpc": "application/vnd.mpohun.certificate",
"mpe": "video/mpeg",
"mpeg": "video/mpeg",
"mpg": "video/mpeg",
"mpg4": "video/mp4",
"mpga": "audio/mpeg",
"msg": "application/vnd.ms-outlook",
"ogg": "audio/ogg",
"pdf": "application/pdf",
"png": "image/png",
"pps": "application/vnd.ms-powerpoint",
"prop": "text/plain",
"rar": "application/x-rar-compressed",
"rc": "text/plain",
"rmvb": "audio/x-pn-realaudio",
"rtf": "application/rtf",
"sh": "text/plain",
"tar": "application/x-tar",
"tgz": "application/x-compressed",
"txt": "text/plain",
"wav": "audio/x-wav",
"wma": "audio/x-ms-wma",
"wmv": "audio/x-ms-wmv",
"wps": "application/vnd.ms-works",
"xml": "text/plain",
"xls": "application/vnd.ms-excel",
"xlsx": "application/vnd.ms-excel",
"doc": "application/msword",
"docx": "application/msword",
"ppt": "application/vnd.ms-powerpoint",
"pptx": "application/vnd.ms-powerpoint",
"z": "application/x-compress",
"zip": "application/zip"
}[key];
})