Не удается открыть zip-файл после загрузки через приложение nodejs из-за ошибки CEN
Мне нужно скачать и распаковать zip-архив в моем приложении nodejs. У меня есть этот код:
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);
}
});
Этот код дает мне ошибку:
Невозможно создать zip, неверные данные. Неправильный заголовок CEN (неверная подпись).
Я использую Windows 7. Я даже не могу открыть этот файл ZIP с 7-Zip или WinRAR (простая ошибка, как поврежденные данные).
Также, 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;
}
Как я могу решить мою проблему?
PS: у меня нет проблем с использованием curl
:)
2 ответа
Проблема в том, что вы декодируете полученные данные в строку utf8:
request.on('data', function (dataBlock) {
loadedData += dataBlock.toString('utf8'); // this is wrong
});
Поскольку zip-файл является двоичным, вы должны использовать буфер.
Вот пример замены для вашего 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;
}
(Добавление в качестве ответа, чтобы я мог опубликовать фрагмент кода)
Я думаю, что @vincent находится на правильном пути - звучит так, будто вы не записываете данные как двоичные в файл. Часто проще просто направить запрос на загрузку прямо в файл:
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);
}
})
Не зная, откуда берется utils.apiRequest, трудно сказать, работает ли это для вас, но, надеюсь, это поможет.