Leonid Zadorozhnykh Leonid Zadorozhnykh -4 years ago 123
Javascript Question

How to download multiple files from Google Drive as .zip using JSZip on Salesforce

The case:
On Salesforce platform I use Google Drive to store files (images for this case) with configured Apex Google Drive API Framework. So Google Drive API handles authToken and so on. I can upload and browse images in my application. In my case I want to select multiple files and download them in a single zip file. So far I'm trying to do that using

JSZip
and
FileSaver
libraries. With the same code below I can zip and download multiple files stored somewhere else with proper response header, but not from GDrive because of CORS error.

https://xxx.salesforce.com/contenthub/download/XXXXXXXXXX%3Afile%XXXXXX_XXXXXXXXX. No'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://xxx.visual.force.com' is therefore not allowed access.
If I just click on this link, file starts to download.

Is there any way to configure GDrive to enable response header:
Access-Control-Allow-Origin: *
or
Access-Control-Allow-Origin: https://*/mydomain.com
somehow or I just have to use something else, maybe server side compression? Now I am using the download link provided by Apex Google Drive API (looks like this:
https://xxx.salesforce.com/contenthub/download/XXXXXXXXXXX%3Afile%XXXXXXXX
), it works fine when used as
src="fileURL"
or when pasted directly to the browser. GDrive connector add 'accesToken' and so on.

My code:

//ajax request to get files using JSZipUtils
let urlToPromise = (url) =>{
return new Promise(function(resolve, reject) {
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
reject(err);
} else {
resolve(data);
}
});
});
};

this.downloadAssets = () => {
let zip = new JSZip();
//here 'selectedAssets' array of objects each of them has 'assetFiles'
//with fileURL where I have url. Download and add them to 'zip' one by one
for (var a of this.selectedAssets){
for (let f of a.assetFiles){
let url = f.fileURL;
let name = a.assetName + "." + f.fileType;
let filename = name.replace(/ /g, "");
zip.file(filename, urlToPromise(url), {binary:true});
}
}
//generate zip and download using 'FileSaver.js'
zip.generateAsync({type:"blob"})
.then(function callback(blob) {
saveAs(blob, "test.zip");
});
};


I also tried to change
let url = f.fileURL
to
let url = f.fileURL + '?alt=media';
and
&access_token=CURRENT_TOKEN
added by GDrive connector.

this link handled by GRDrive connector so if I just enter it in browser it download the image. However, for multiple download using JS I got CORS error.

Answer Source

My previously published code works. Forgot to post a solution. Just instead of using content hub link I started to use direct link to Google Drive and CORS issue was solved. Still not sure if CORS might be solved somehow at Salesforce side. Tried different setups with no luck. Direct download link to GDrive works ok in my case. The only thing I had to change is the prefix to GDrive file ID.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download