Skip to content

Instantly share code, notes, and snippets.

@rajeevprasanna
Created October 8, 2017 11:02
Show Gist options
  • Save rajeevprasanna/327be60b176fa4c1129aca456d9e1d57 to your computer and use it in GitHub Desktop.
Save rajeevprasanna/327be60b176fa4c1129aca456d9e1d57 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<title>File downloader</title>
</head>
<body>
<div id="progress-msg">File is downloading. Please wait...</div>
<script>
function saveAs(blob, fileName) {
var url = window.URL.createObjectURL(blob);
var anchorElem = document.createElement("a");
anchorElem.style = "display: none";
anchorElem.href = url;
anchorElem.download = fileName;
document.body.appendChild(anchorElem);
anchorElem.click();
document.body.removeChild(anchorElem);
// On Edge, revokeObjectURL should be called only after
// a.click() has completed, atleast on EdgeHTML 15.15048
setTimeout(function() {
window.URL.revokeObjectURL(url);
}, 1000);
}
function downloadFile(fileName, fileUrl){
var xhr = new XMLHttpRequest();
xhr.open("GET", fileUrl, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function() {
arrayBuffer = this.result;
var byteCharacters = atob(new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), ''));
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob1 = new Blob([byteArray], {type: "application/octet-stream"});
saveAs(blob1, fileName);
document.getElementById('progress-msg').innerHTML = 'File download completed!!!';
};
fileReader.readAsArrayBuffer(blob);
}else{
document.getElementById('progress-msg').innerHTML = 'Error in downloading file. Please try again!!!';
}
};
xhr.onerror = function(e) {
document.getElementById('progress-msg').innerHTML = 'Error in downloading file. Please try again!!!';
};
xhr.send();
}
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
//params = new URLSearchParams(window.location.search)
//url = params.get('url');
url = getParameterByName('url', window.location.search);
fileName = getParameterByName('fileName', window.location.search);
if(url){
fileName = fileName ? fileName :'newFile';
downloadFile(fileName, url);
}
</script>
</body>
</html>
@rajeevprasanna
Copy link
Author

i understood what u r doing. u r directly downloading blob in outlook addin and then trying to open it by giving to script. It wont't work that way.

u can never open blob directly from browser. it will throw error u got.

If ur blob is download from a link, then construct a link like below :
ex : s3URL is the blob url where content is encoded. and targetFileName is file name which will be save into browser with given name.

i hosted my above html with script in location : https://sf.xenovusapps.net

now the target url : "https://sf.xenovusapps.net/fd?fileName=" + encodeURIComponent(targetFileName) + "&url=" + encodeURIComponent(s3URL);

when user clicks on this link, it will be opened in browser and file automatically downloaded and saved to file system.

ex : https://sf.xenovusapps.net/fd?fileName=test.jpg&url=https%3A%2F%2Fdorm.s3.amazonaws.com%2F6818e1b592bafc815545d065d2b7ef85de5685229e11712176aaad1fcbb9d8f2%3FSignature%3Du%252B8LD4KKZJFJhkrUUQ%252Bs4L56Wh0%253D%26Expires%3D1539061262%26AWSAccessKeyId%3DAKIAJ66BMFSXF56WIKNA

@OriAmir
Copy link

OriAmir commented Oct 9, 2017

First,Thank you very much for your help.
I didn't really understand your soultion yet.
What I do until now and works in all my tests instead outlook desktop for mac( all browsers in windows and mac and outlook desktop for windows) was to create the blob like I do above(last comment) and then use 'saveAs' functiuon from FileSaver library: https://github.com/eligrey/FileSaver.js/

Now, I try to understand your solution.:
what you mean by 'If ur blob is download from a link' ? I create my blob on client side from content I get from server.
What you man by 's3URL is the blob url where content is encoded'? You mean the URL when using this: window.URL.createObjectURL(blob) ?
I don't understand how you get this link at the end of all the procedure ? https://sf.xenovusapps.net/fd?fileName=test.jpg&url=https%3A%2F%2Fdorm.s3.amazonaws.com%2F6818e1b592bafc815545d065d2b7ef85de5685229e11712176aaad1fcbb9d8f2%3FSignature%3Du%252B8LD4KKZJFJhkrUUQ%252Bs4L56Wh0%253D%26Expires%3D1539061262%26AWSAccessKeyId%3DAKIAJ66BMFSXF56WIKNA
Where is the blob url in this link,I don't really understand how you build this url?

Thank you very much again !!!!

@mihirsn
Copy link

mihirsn commented Apr 11, 2019

@rajeevprasanna, we are also facing the same issue like @OriAmir.
We are developing outlook web add-in where we want to download file from outlook2016 client for Mac (OS : MacOS High Sierra). So tried to implement the above solution, but getting error as Failed to load resource: The operation couldn't be completed.(WebKitBlobResource error 1.).

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