Как загрузить несколько файлов с Google Диска в формате .zip с помощью JSZip в Salesforce

Случай: на платформе Salesforce я использую Google Диск для хранения файлов (в данном случае изображений) с настроенной Apex Google Drive API Framework. Таким образом, Google Drive API обрабатывает authToken и так далее. Я могу загружать и просматривать изображения в своем приложении. В моем случае я хочу выбрать несколько файлов и загрузить их одним zip-файлом. Пока я пытаюсь сделать это, используя библиотеки JSZip и FileSaver. С тем же кодом ниже я могу заархивировать и загрузить несколько файлов, хранящихся где-то еще, с правильным заголовком ответа, но не с GDrive из-за ошибки CORS.

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

Я также попытался изменить let url = f.fileURL на let url = f.fileURL + '?alt=media'; и &access_token=CURRENT_TOKEN, добавленные коннектором GDrive.

эта ссылка обрабатывается коннектором GRDrive, поэтому, если я просто введу ее в браузере, она загрузит изображение. Однако при многократной загрузке с использованием JS я получил ошибку CORS.


person Leonid Zadorozhnykh    schedule 19.11.2016    source источник


Ответы (3)


Я думаю, что эта функция еще не поддерживается. Если вы прочитаете руководство по загрузке файлов из Drive API, там нет упоминания загрузки нескольких файлов одновременно. Это потому, что вам нужно делать отдельные запросы API для каждого файла. Это подтверждается в этом Тема ТАК.

Но выбранные несколько файлов преобразуются в один zip-файл и загружаются в этот единственный zip-файл, что возможно с помощью API-интерфейса Google Drive. Итак, как я могу преобразовать их в один Zip-файл? пожалуйста, скажите мне.

person noogui    schedule 21.11.2016
comment
Да, я не нашел ничего для загрузки нескольких файлов напрямую с GDrive. Я пытаюсь загрузить один файл за раз здесь urlToPromise = (url) с запросом AJAX. Я пытаюсь сделать следующее: 1. Загрузить один файл 2. Заархивировать файлы в один файл (на стороне клиента с помощью JavaScript) 3. Загрузить это zip Мне нужно что-то вроде самого GDrive, где можно загрузить несколько файлов в виде zip . - person Leonid Zadorozhnykh; 21.11.2016

По моему мнению, просто загрузите все файлы и сохраните их во временном каталоге, а затем добавьте этот каталог в 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;
    }
person Srusti Thakkar    schedule 15.02.2017

Мой ранее опубликованный код работает. Забыл написать решение. Просто вместо использования ссылки на концентратор контента я начал использовать прямую ссылку на Google Диск, и проблема CORS была решена. Все еще не уверен, что CORS можно как-то решить на стороне Salesforce. Пробовал разные настройки, безрезультатно. Прямая ссылка для скачивания на GDrive в моем случае работает нормально. Единственное, что мне пришлось изменить, это префикс к идентификатору файла GDrive.

person Leonid Zadorozhnykh    schedule 01.03.2017