简体   繁体   English

由于无效的CEN错误,通过nodejs应用程序下载后无法打开zip文件

[英]Can not open zip file after downloading through nodejs application because of Invalid CEN error

I need to download and unzip zip archive in my nodejs application. 我需要在我的nodejs应用程序中下载并解压缩zip存档。 I have this code: 我有以下代码:

utils.apiRequest(teamcityOptions)
        .then(function (loadedData) {
          var tempDir = tmp.dirSync();
          var tmpZipFileName = tempDir.name + "\\" + 'bob.zip';

          fs.appendFileSync(tmpZipFileName, loadedData);

          var zip;
          try {
            zip = new AdmZip(tmpZipFileName);
          } catch (e) {
            log('Can not create zip, bad data', e);
          }
        });

This code gives me error: 这段代码给我错误:

Can not create zip, bad data Invalid CEN header (bad signature) 无法创建zip,数据错误CEN标头无效(签名错误)

I am using Windows 7. I can't even open this ZIP file with 7-zip or WinRAR (simple error like corrupted data). 我使用的是Windows7。我什至无法使用7-zip或WinRAR(诸如损坏的数据之类的简单错误)打开此ZIP文件。

Also, utils.apiRequest function body is: 另外, utils.apiRequest函数主体为:

utils.apiRequest: function (options) {
  var deferred = defer();
  https.get(options, function (request) {
    var loadedData = '';
    request.on('data', function (dataBlock) {
      loadedData += dataBlock.toString('utf8');
    });
    request.on('end', function () {
      deferred.resolve(loadedData);
    })
  });
  return deferred.promise;
}

How can I solve my problem? 我该如何解决我的问题?

PS: I don't have problems using curl :) PS:我没有使用curl问题:)

The problem is that you're decoding the received data into an utf8 string: 问题是您要将接收到的数据解码为utf8字符串:

request.on('data', function (dataBlock) {
  loadedData += dataBlock.toString('utf8'); // this is wrong
});

Since a zip file is binary you should use a Buffer. 由于zip文件是二进制文件,因此您应该使用Buffer。

Here is an example replacement for your utils.apiRequest with Buffer: 这是用Buffer替换utils.apiRequest的示例:

utils.apiRequest: function (options) {
    var deferred = defer();
    https.get(options, function (request) {
        var data = []; 
        request.on('data', function (dataBlock) {
            data.push(dataBlock); 
        });
        request.on('end', function () {
            deferred.resolve(Buffer.concat(data));
        });
    });
    return deferred.promise;
}

(Adding as an answer so I can post the code snippet) (添加为答案,以便我可以发布代码段)

@vincent is on the right track I think - sounds like you're not writing the data as binary to the file. 我认为@vincent处在正确的轨道上-听起来好像您没有将数据以二进制形式写入文件。 It's often easier to just pipe a download request straight to a file: 将下载请求直接传送到文件通常更容易:

var http = require('http');
var fs = require('fs');
var AdmZip = require('adm-zip')

var tmpZipStream = fs.createWriteStream('bob.zip');
var request = http.get('http://example.com/example.zip', function(response) {
  response.pipe(tmpZipStream);
});

tmpZipStream.on('close', function() {
  var zip;
  try {
    zip = new AdmZip('bob.zip');
  } catch (e) {
    console.log('Can not create zip, bad data', e);
  }
})

Without knowing where utils.apiRequest comes from it's hard to say if this is workable for you, but hopefully it helps. 不知道utils.apiRequest来自何处,很难说这是否对您有用,但希望它会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM