Как обновить ZIP-файл в Google Диске с помощью Google Drive Javascript API - PullRequest
0 голосов
/ 17 мая 2018

Я совершенно неопытен со сжатием файлов и API Google Drive.В моем проекте я использую zip.js и Google Drive Api.Zip.js работает хорошо, потому что я загружаю напрямую сгенерированный zip-файл, и мое устройство может распаковать его.Даже если я не добавляю никаких дополнительных данных к содержимому zip-файла, размер zip-файла изменяется (удваивается) и повреждается при его обновлении.

Моя функция для создания zip-файла:

function createZip(data,fileName,callback){
    var blob = new Blob([ data ], {
      type : "text/xml"
    });

    zipBlob(fileName, blob, function(zippedBlob){
        console.log(zippedBlob)
        // saveAs(zippedBlob,"test.zip") //this test.zip is a valid file.
        var reader = new FileReader();
        reader.addEventListener("loadend", function() {
           // reader.result contains the contents of blob as a typed array
           console.log(reader.result);
           callback(reader.result);
        });
        reader.readAsText(zippedBlob)
    })


    function zipBlob(filename, blob, callback) {
      zip.createWriter(new zip.BlobWriter("application/zip"), function(zipWriter) {
        zipWriter.add(filename, new zip.BlobReader(blob), function() {
          zipWriter.close(callback);
        });
      }, function(error){
        console.error(error)
      });
    }
}

Моя функция обновления файла:

this.updateFile = function(id, text, accessToken, callback) {
    var boundary = '-------314159265358979323846',
        delimiter = "\r\n--" + boundary + "\r\n",
        close_delim = "\r\n--" + boundary + "--",
        mimeType = 'application/zip';

    var multipartRequestBody =
        delimiter + 'Content-Type: application/json\r\n\r\n' +
        delimiter + 'Content-Type:' + mimeType + '\r\n\r\n' +
        text +
        close_delim;

    gapi.client.request({
        'path': '/upload/drive/v3/files/'+id,
        'method': 'PATCH',
        'params': { 'uploadType': 'multipart' },
        'headers': { 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + accessToken, },
        'body': multipartRequestBody
    }).execute(function(file) {
        if (typeof callback === "function") callback(file);
    }, function(error) {
        console.error(error)
        callback(error);
    });
}

Интересно, не повреждает ли FileReader содержимое, потому что reader.result отличается от исходного содержимого zip.Я использую эту функцию для чтения содержимого файла:

this.readFile = function(fileId, callback) {
    var request = gapi.client.drive.files.get({
        fileId: fileId,
        alt: 'media',
        Range : 'bytes=100-200'
    })
    request.then(function(response) {
        console.log(response);
        if (typeof callback === "function") callback(response.body);
    }, function(error) {
        console.error(error)
    })
    //return request;
}

Исходное содержимое zip в виде текста:

PKÊL    PV-A2.xmlUXñçûZÂÌZùì½m,I÷]þC£?I@ÌNøK¼=F °KÃ(­«Ýgz=Crçß+²ne§y¸¥U6... (some thousands characters more)

Содержимое программы чтения файлов в виде текста:

PK�U�L  PV-A2.xml�]�<��w�O1�+(���� �@�6`@+  �Ґ`��r��EÑ�������̊s"���0�..(some thousands characters more)

РЕШЕНИЕ

Получить данные base64 из zip-файла (не забудьте вырезать data:application/zip;base64, out):

    // saveAs(zippedBlob,"test.zip") //this test.zip is a valid file.
    var reader = new FileReader();
    reader.addEventListener("loadend", function() {
       // reader.result contains the contents of blob as a typed array
       callback(reader.result.replace("data:application/zip;base64,",""));
    });
    reader.readAsDataURL(zippedBlob)

Добавить Content-Transfer-Encoding: base64 в multipartRequestBody и использоватьсодержимое base64.

var multipartRequestBody =
    delimiter + 'Content-Type: application/json\r\n\r\n' +
    delimiter + 'Content-Type:' + mimeType + '\r\n' +
    'Content-Transfer-Encoding: base64\r\n\r\n' +
    base64Data +
    close_delim;

1 Ответ

0 голосов
/ 17 мая 2018

Если text - это zip-файл, который был преобразован в base64, как насчет этой модификации?Я думаю, что ваш сценарий почти правильный.В качестве модификации, он дает метод кодирования файла, используя Content-Transfer-Encoding.

From:

delimiter + 'Content-Type:' + mimeType + '\r\n\r\n' +
text +

To:

delimiter + 'Content-Type: ' + mimeType + '\r\n' + // Modified
'Content-Transfer-Encoding: base64\r\n\r\n' + // Added
text +

Примечание:

  • В моем окружении я подтвердил, что та же ошибка с вашей ситуацией происходит при использовании вашего скрипта.А также я подтвердил, что когда это изменение отражается в вашем сценарии, zip-файл обновляется, и его можно разархивировать.

Но если это не было решением вашей ситуации, яизвините.

...