Конвертируйте файлы загрузки curl для запроса в Node.JS и запишите zip-файл

Я пытаюсь преобразовать следующий локон в запрос узла.

curl -F files[]=@database.mdb 'https://www.rebasedata.com/api/v1/convert?outputFormat=mysql&errorResponse=zip' -o output.zip

Я пытался использовать запрос или node-libcurl, но не могу найти способ загрузить файл MDB.

Код у меня есть

var request = require('request');

var options = {
    url: 'https://www.rebasedata.com/api/v1/convert?outputFormat=mysql&errorResponse=zip',
    method: 'POST',
    formData: {
        custom_file: {
            options: {
            contentType: 'application/mdb'
        },
            value: path.resolve(__dirname, 'myMdb.mdb') 
        }
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);

Но я продолжал получать ошибку как никакие файлы дано или не мог открыть файл.

Любая помощь приветствуется.

2 ответа

Решение

У вас есть несколько ошибок:

  • key из curl заявление files[]не custom_fileэто всего лишь пример request документ здесь https://github.com/request/request. Поэтому, пожалуйста, измените его на files[]
  • Документ о request также сказал, что значение должно быть stream, а не путь
  • Вы должны требовать path а также fs создать поток и прочитать файл пути

Отредактировано: Как записать zip-файл из resoponse?

Вы хотите написать почтовый файл, пожалуйста, ссылку на пакет JSZip https://stuk.github.io/jszip/documentation/howto/read_zip.html. После есть body, прочитайте zip и запишите в zip файл.

Я сделал вашу проблему с новым кодом, обработчик обратного вызова из документа request, вы можете игнорировать мой обработчик обратного вызова.

Обновленный почтовый файл

Прежде чем установить пакет jszip

npm install jszip --save

И это код, пожалуйста, добавьте кодировку: null при запросе:

var request = require('request');
var path = require('path');
var fs = require('fs');
var JSZip = require("jszip");

function callback(error, response, body) {
    if (error || response.statusCode !== 200) {
        console.log(error);
        return;
    }
    JSZip.loadAsync(body).then(zip => {
        console.log(zip.files);
        zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
            .pipe(fs.createWriteStream(path.join(__dirname, './out.zip')))
            .on('finish', function () {
                console.log("File written");
            });
    }).catch(err => console.log(err))
}

request({
    url: 'https://www.rebasedata.com/api/v1/convert?outputFormat=mysql&errorResponse=zip',
    method: 'POST',
    encoding: null, // <--------- important ----------
    formData: {
        'files[]': {
            options: {
                filename: 'database.mdb',
                contentType: 'application/mdb'
            },
            value: fs.createReadStream(path.resolve(__dirname, './database.mdb'))
        }
    }
}, callback);

Мой файл database.mdb загружен здесь https://ufile.io/prnsi (файл будет удален через 30 дней после опубликованного ответа).

И когда console.log(zip.files);, вы получите из моего файла базы данных

{ 'data.sql':
   { name: 'data.sql',
     dir: false,
     date: 2018-12-17T02:09:08.000Z,
     comment: null,
     unixPermissions: 33206,
     dosPermissions: null,
     _data:
      { compressedSize: 643,
        uncompressedSize: 1817,
        crc32: 1832401262,
        compression: [Object],
        compressedContent: <Buffer 9d 54 6d 6f a2 40 10 fe 7c fc 8a b9 4f da 56 da c5 7a 46 bd 98 88 b0 b6 44 5c ae 80 f7 d2 2f 88 b0 6d 49 10 1a 5e 9a f6 df df 02 be 80 40 7a 39 02 c9 ... > },
     _dataBinary: true,
     options: { compression: null, compressionOptions: null } } }

Похоже, у вас могут быть две проблемы:

  1. Если curl оператор верен, тогда сервер ожидает поле формы, содержащее файл, который будет вызван files[]не custom_file как у вас в вашем примере nodejs.

  2. Вы передаете строку (имя файла), а не поток (содержимое файла).

Попробуйте что-то вроде этого:

var request = require('request');

var options = {
    url: 'https://www.rebasedata.com/api/v1/convert?outputFormat=mysql&errorResponse=zip',
    method: 'POST',
    formData: {
        'files[]': {
            options: {
                contentType: 'application/mdb'
            },
            value: fs.createReadStream(path.resolve(__dirname, 'myMdb.mdb'))
        }
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);

(Я бы также заглянул на https://github.com/request/request-promise; у него тот же формат запроса, но вместо этого вы можете отказаться от обратных вызовов и использовать обещания, что считается идиоматическим и будет легче в долгосрочной перспективе.)

Другие вопросы по тегам