API Google Диска - получить файл и zip с помощью JSZip возвращает поврежденный файл

Я использую API Google Диска, чтобы получить BLOB файл и попытка передать эти данные BLOB в JSZip для архивирования, но у меня проблемы.

Конкретный фрагмент выглядит следующим образом:

var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://www.googleapis.com/drive/v3/files/"+file_id+"?alt=media",
    "method": "GET",
    "headers": {
        "responseType": "blob",
        "Authorization": "Bearer "+bearer_token
     }
}

$.ajax(settings).done(function (response, status, xhr) {
    console.log(response);
    zip.file(filename, response);

    zip.generateAsync({type:"blob"}, function updateCallback(metadata) {
        var msg = "progression : " + metadata.percent.toFixed(2) + " %";
        if(metadata.currentFile) {
            msg += ", current file = " + metadata.currentFile;
        }
        showMessage(msg);
        updatePercent(metadata.percent|0);
     })
     .then(function callback(blob) {
         saveAs(blob, "example.zip");
         showMessage("done !");
     }, function (e) {
         showError(e);
     });
 });

Я использовал Postman для тестирования API, которое давало ожидаемые результаты. Я попытался заархивировать несколько файлов изображений/pdf/zip, и все они вернулись поврежденными. Единственное, что работало до сих пор, — это PHP-файл. API Google Диска правильно возвращает данные BLOB, и все выглядит правильно в сгенерированном JSZip zip-файле (имя файла, размер файла и т. д.), но при открытии файла из zip я получаю ошибки, указывающие на то, что файл поврежден.

Любые идеи?

Заранее спасибо за помощь!


person awl19    schedule 05.08.2019    source источник
comment
Мой ответ показал вам результат, который вы хотите? Не могли бы вы рассказать мне об этом? Это также полезно для меня, чтобы учиться. Если это сработает, другие люди, у которых есть такая же проблема, как и вы, могут также обосновать ваш вопрос как вопрос, который можно решить. Если у вас есть вопросы для моего ответа еще, я извиняюсь. В то же время, могу я спросить вас о вашей текущей ситуации? Я хотел бы учиться, чтобы решить ваши проблемы.   -  person Tanaike    schedule 10.08.2019
comment
Эй, извините за задержку! Большое вам спасибо за вашу помощь. Это сработало! Ваши изменения помогли создать URL-адрес BLOB, который я смог реализовать в JSZip, заменив исходную функцию zip.file на zip.file(filename, urlToPromise(URL.createObjectURL(blob)), {binary:true}); и теперь zip-файл возвращает неповрежденный файл.   -  person awl19    schedule 10.08.2019
comment
Спасибо за ответ и дополнительную информацию. Я рад, что ваша проблема была решена. И тебе спасибо.   -  person Tanaike    schedule 10.08.2019


Ответы (1)


  • Вы хотите получить zip-файл с Google Диска.
  • Вы хотите добиться этого с помощью Javascript.
  • Вы уже смогли получить и поместить файл с помощью Drive API.

Если я правильно понимаю, как насчет этой модификации?

Пункт модификации:

  • I think that the reason of your issue is that the zip file is retrieved as the string data.
    • For this situation, I used fetch.

Модифицированный скрипт:

Пожалуйста, измените следующим образом.

From:
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://www.googleapis.com/drive/v3/files/"+file_id+"?alt=media",
    "method": "GET",
    "headers": {
        "responseType": "blob",
        "Authorization": "Bearer "+bearer_token
     }
}

$.ajax(settings).done(function (response, status, xhr) {
To:
const url = "https://www.googleapis.com/drive/v3/files/" + file_id + "?alt=media";
fetch(url, {
  method: "GET",
  dataType: "binary",
  responseType: "blob",
  headers: {Authorization: "Bearer " + bearer_token},
  // crossDomain: true, // This might not be required.
})
.then(res => res.blob())
.then(response => {
  • В приведенном выше модифицированном скрипте response — это большой двоичный объект.
  • Пожалуйста, установите file_id и bearer_token

Для тестирования:

В качестве тестового примера сценария, как насчет следующего сценария? Когда вы запускаете этот сценарий, загруженный zip-файл сохраняется на локальном ПК с именем файла sample.zip. Я подумал, что скрипт можно будет протестировать с помощью этого скрипта.

const url = "https://www.googleapis.com/drive/v3/files/" + file_id + "?alt=media";
fetch(url, {
  method: "GET",
  dataType: "binary",
  responseType: "blob",
  headers: {Authorization: "Bearer "+bearer_token},
})
.then(res => res.blob())
.then(blob => {
  var a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.target = "_blank";
  a.download = "sample.zip";
  a.click();
});

Примечание:

  • Это простой пример скрипта. Поэтому, пожалуйста, измените это для вашей ситуации.

Рекомендации:

Если я неправильно понял ваш вопрос, и это было не то направление, которое вам нужно, приношу свои извинения.

person Tanaike    schedule 06.08.2019
comment
причина, по которой он потерпел неудачу, заключалась в том, что он использовал responseType в заголовке, а выборка не поддерживает dataType или responseType, поэтому параметры должны быть удалены. - person Endless; 28.08.2019