I'm currently working on adding the capability to download a file stored on a server. To access the file, I need to include the Authorization
header, requiring me to send an XHR request to retrieve the file from the server. Since the file content is stored in a variable, I have to create a data URL to set it as the href
attribute of an anchor tag and simulate a click event to initiate the file download programmatically.
The functionality works well in most browsers (with a separate code for IE11), but I am encountering errors specifically in iOS Safari versions. Below is the code snippet I am using -
var isBrowserIE = window.navigator && window.navigator.msSaveOrOpenBlob;
var dataHref = 'https://example.com/doc.pdf';
var xhr = new XMLHttpRequest();
xhr.open('GET', dataHref, true);
xhr.setRequestHeader('Content-Type', 'application/pdf');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.responseType = isBrowserIE ? 'blob' : 'arraybuffer';
xhr.onload = function (e) {
if (this.status == 200) {
//For IE11
if (isBrowserIE) {
var blob = new Blob([this.response], { type: 'application/pdf' });
var bool = window.navigator.msSaveOrOpenBlob(blob, docName);
if (!bool) {
alert("Download failed, Please try again later");
}
} else {
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
var dataUrl = 'data:application/octet-stream;charset=utf-16le;base64,' + base64;
var element = document.createElement('a');
element.setAttribute('href', dataUrl);
element.setAttribute('download', 'doc.pdf');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
} else {
alert("Download failed, Please try again later");
closeWindow();
}
};
xhr.send();
The error I'm facing is related to Safari and reads -
Safari cannot open the page.<br><br>The error was: “Data URL decoding failed”.
I'm unsure what may be causing this error. It seems to only occur on iPad 4 and iPad 5, while still working on iPad mini and iPhone XR devices. The inconsistency across different iOS versions is puzzling.