Skip to content

Instantly share code, notes, and snippets.

@sempostma
Last active December 26, 2023 15:12
Show Gist options
  • Save sempostma/be25fabfe94b1982e971aaf26a54c999 to your computer and use it in GitHub Desktop.
Save sempostma/be25fabfe94b1982e971aaf26a54c999 to your computer and use it in GitHub Desktop.
Downloading/Saving/Opening files with Cordova in javascript and polyfill the achor's download attribute for android webview.
"use strict";
if (window.cordova && cordova.platformId !== "browser") {
document.addEventListener("deviceready", function () {
document.addEventListener("click", function (e) {
var elem = e.target;
while (elem != document) {
if (elem.tagName === "A" && elem.hasAttribute("download")) {
e.preventDefault();
if (elem.getAttribute("href").slice(0, 5) === "data:") {
var blob = dataURItoBlob(elem.getAttribute("href"));
download(elem.getAttribute("download"), blob, blob.type);
} else {
fetch(elem.getAttribute("href"))
.then(function (response) {
return response.blob();
})
.then(function (blob) {
return download(elem.getAttribute("download"), blob, blob.type);
});
}
return;
}
elem = elem.parentNode;
}
});
})
}
function download(filename, data, mimeType) {
var blob = new Blob([data], {
type: mimeType
});
if (window.cordova && cordova.platformId !== "browser") {
document.addEventListener("deviceready", function() {
var storageLocation = "";
switch (device.platform) {
case "Android":
storageLocation = cordova.file.externalDataDirectory;
break;
case "iOS":
storageLocation = cordova.file.documentsDirectory;
break;
}
var folderPath = storageLocation;
window.resolveLocalFileSystemURL(
folderPath,
function(dir) {
dir.getFile(
filename,
{
create: true
},
function(file) {
file.createWriter(
function(fileWriter) {
fileWriter.write(blob);
fileWriter.onwriteend = function() {
var url = file.toURL();
cordova.plugins.fileOpener2.open(url, mimeType, {
error: function error(err) {
console.error(err);
alert("Unable to download");
},
success: function success() {
console.log("success with opening the file");
}
});
};
fileWriter.onerror = function(err) {
alert("Unable to download");
console.error(err);
};
},
function(err) {
// failed
alert("Unable to download");
console.error(err);
}
);
},
function(err) {
alert("Unable to download");
console.error(err);
}
);
},
function(err) {
alert("Unable to download");
console.error(err);
}
);
});
} else {
saveAs(blob, filename);
}
}
function dataURItoBlob(dataURI) {
var isBase64 = dataURI.split(",")[0].split(";")[1] === "base64";
var byteString;
if (isBase64) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
byteString = atob(dataURI.split(",")[1]);
} else {
byteString = dataURI.split(",")[1];
} // separate out the mime component
var mimeString = dataURI
.split(",")[0]
.split(":")[1]
.split(";")[0]; // write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length); // create a view into the buffer
var ia = new Uint8Array(ab); // set the bytes of the buffer to the correct values
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
} // write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], {
type: mimeString
});
return blob;
});
@robinyip
Copy link

The downloaded file is still URIEncoded, how can I solve it? Tried to decodeURIComponent( byteString) but no luck, many thanks

@robinyip
Copy link

sample:
data:text/csv;charset=utf-8,%EF%BB%BFSchedule%0D%0A%0ALoading%20Port%2CETD%2CDischarge%20Port%2CETA%2CTranshipment%20Port%2CT%2FT%2CVessel%20Name%2CVoyage%20No.%2CIMO%20No.%2COperator%2CService%2C2nd%20Leg%20Vessel%20Name%2C2nd%20Leg%20Voyage%20No.%2CSI%20Cut-off%2CVGM%20Cut-off%2CCY%20Closing%2CCFS%20Closing%2CReceiving%2CVR%20Closing%2CCV%20Cut-off%0D%0A%22Hong%20Kong%20%E9%A6%99%E6%B8%AF%22%2C%222020-11-17%22%2C%22Nottingham%20%E8%AB%BE%E4%B8%81%E6%BC%A2%22%2C%222020-12-20%22%2C%22%20%22%2C%2233%20Days%22%2C%22EVER%20LUCKY%22%2C%221071-043E%22%2C%22%22%2C%22OOCL%22%2C%22ECC1%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%222020-11-15%2023%3A00%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%0D%0A%22Hong%20Kong%20%E9%A6%99%E6%B8%AF%22%2C%222020-11-24%22%2C%22Nottingham%20%E8%AB%BE%E4%B8%81%E6%BC%A2%22%2C%222020-12-27%22%2C%22%20%22%2C%2233%20Days%22%2C%22TAMPA%20TRIUMPH%22%2C%221072-019E%22%2C%22%22%2C%22OOCL%22%2C%22ECC1%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%222020-11-22%2023%3A00%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%0D%0A%22Hong%20Kong%20%E9%A6%99%E6%B8%AF%22%2C%222020-12-01%22%2C%22Nottingham%20%E8%AB%BE%E4%B8%81%E6%BC%A2%22%2C%222021-01-03%22%2C%22%20%22%2C%2233%20Days%22%2C%22EVER%20LYRIC%22%2C%221073-036E%22%2C%22%22%2C%22OOCL%22%2C%22ECC1%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%222020-11-29%2023%3A00%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%0D%0A%22Hong%20Kong%20%E9%A6%99%E6%B8%AF%22%2C%222020-12-08%22%2C%22Nottingham%20%E8%AB%BE%E4%B8%81%E6%BC%A2%22%2C%222021-01-10%22%2C%22%20%22%2C%2233%20Days%22%2C%22EVER%20FORWARD%22%2C%221074-002E%22%2C%22%22%2C%22OOCL%22%2C%22ECC1%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%222020-12-06%2023%3A00%22%2C%22%22%2C%22%22%2C%22%22%2C%22%22%2C%0D%0A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment