【问题标题】:How to download multiple files from Google Drive as .zip using JSZip on Salesforce如何在 Salesforce 上使用 JSZip 从 Google Drive 下载多个 .zip 文件
【发布时间】:2016-11-19 10:54:45
【问题描述】:

案例: 在 Salesforce 平台上,我使用配置了 Apex Google Drive API 框架 的 Google Drive 来存储文件(本案例的图像)。所以 Google Drive API 处理 authToken 等等。我可以在我的应用程序中上传和浏览图像。就我而言,我想选择多个文件并将它们下载到一个 zip 文件中。到目前为止,我正在尝试使用 JSZipFileSaver 库来做到这一点。使用下面相同的代码我可以压缩和下载存储在其他地方的具有正确响应头的多个文件,但由于 CORS 错误而不能从 GDrive。

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.如果我点击这个链接,文件就会开始下载。

有什么方法可以配置 GDrive 以启用响应标头:Access-Control-Allow-Origin: *Access-Control-Allow-Origin: https://*/mydomain.com 或者我只需要使用其他东西,也许是服务器端压缩?现在我正在使用 Apex Google Drive API 提供的下载链接(如下所示: https://xxx.salesforce.com/contenthub/download/XXXXXXXXXXX%3Afile%XXXXXXXX),当用作 src="fileURL" 或直接粘贴到浏览器时,它可以正常工作。 GDrive 连接器添加 'accesToken' 等。

我的代码:

//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");
    });       
};

我还尝试将 GDrive 连接器添加的 let url = f.fileURL 更改为 let url = f.fileURL + '?alt=media';&access_token=CURRENT_TOKEN

此链接由 GRDrive 连接器处理,因此如果我只是在浏览器中输入它,它会下载图像。但是,对于使用 JS 进行多次下载,我得到了 CORS 错误。

【问题讨论】:

    标签: javascript google-drive-api salesforce apex jszip


    【解决方案1】:

    我认为此功能尚不支持。如果您从 Drive API 检查Download Files guide,则没有提到一次下载多个文件。那是因为您必须为每个文件发出单独的 API 请求。这在SO thread 中得到了证实。

    但是选择的多个文件将转换为单个 zip 文件并下载单个 zip 文件,这可以通过 google drive API 实现。那么如何将它们转换为单个 Zip 文件呢?请告诉我。

    【讨论】:

    • 是的,我没有找到任何可以直接从 GDrive 下载多个文件的内容。我正在尝试使用 AJAX 请求在 urlToPromise = (url) 一次下载单个文件。我要做的是: 1. 下载单个文件 2. 在一个文件中压缩文件(使用 JavaScript 在客户端) 3. 下载 zip 我需要类似 GDrive 本身的东西,可以下载多个文件作为 zip。
    【解决方案2】:

    据我说,只需下载所有文件并将它们存储在临时目录位置,然后将该目录添加到 zip 文件并将该 zip 存储到物理设备。

     public Entity.Result<Entity.GoogleDrive> DownloadMultipleFile(string[] fileidList)
        {
            var result = new Entity.Result<Entity.GoogleDrive>();
            ZipFile zip = new ZipFile();
    
            try
            {
                var service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Download File",
                });
    
                FilesResource.ListRequest listRequest = service.Files.List();
                //listRequest.PageSize = 10;
                listRequest.Fields = "nextPageToken, files(id, name, mimeType, fullFileExtension)";
    
                IList<File> files = listRequest.Execute().Files;
    
                if (files != null && files.Count > 0)
                {
                    foreach (var fileid in fileidList)
                    {
                        foreach (var file in files)
                        {
                            if (file.Id == fileid)
                            {                                
                                    result.Data = new Entity.GoogleDrive { FileId = fileid };
                                    FilesResource.GetRequest request = service.Files.Get(fileid);
                                    request.ExecuteAsync();
                                    var stream = new System.IO.FileStream(HttpContext.Current.Server.MapPath(@"~\TempFiles") + "\\" + file.Name, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                                    request.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
                                    {
                                        switch (progress.Status)
                                        {
                                            case DownloadStatus.Downloading:
                                                {
                                                    break;
                                                }
                                            case DownloadStatus.Completed:
                                                {
                                                    break;
                                                }
                                            case DownloadStatus.Failed:
                                                {
                                                    break;
                                                }
                                        }
                                    };
                                    request.Download(stream);
                                    stream.Close();
                                    break;
                                }                                
                            }   
                        }
    
                }
                zip.AddDirectory(HttpContext.Current.Server.MapPath(@"~\TempFiles"), "GoogleDrive");
                string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                string pathDownload = System.IO.Path.Combine(pathUser, "Downloads");
                zip.Save(pathDownload + "\\GoogleDrive.zip");
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(HttpContext.Current.Server.MapPath(@"~\TempFiles"));
                foreach (var file in di.GetFiles())
                {
                    file.Delete();
                }
    
                result.IsSucceed = true;
                result.Message = "File downloaded suceessfully";
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Message = ex.ToString();
            }
            return result;
        }
    

    【讨论】:

      【解决方案3】:

      我之前发布的代码有效。忘记发布解决方案。 我没有使用内容中心链接,而是开始使用直接链接到 Google Drive 并解决了 CORS 问题。仍然不确定CORS是否可以在Salesforce方面以某种方式解决。尝试了不同的设置,但没有成功。 在我的情况下,直接下载到 GDrive 的链接可以正常工作。我唯一需要更改的是 GDrive 文件 ID 的前缀。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-04
        • 2020-05-23
        • 1970-01-01
        相关资源
        最近更新 更多