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

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

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

Я пытался использовать request или 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 ]

0 голосов
/ 17 декабря 2018

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

  • Оператор key из curl равен files[], а не custom_file, это только пример request документа здесь https://github.com/request/request#multipartform-data-multipart-form-uploads. Поэтому, пожалуйста, измените его на files[]
  • В документе request также сказано, что значение должно быть stream, а не путем
  • Вам необходимо path иfs чтобы создать поток и прочитать путь к файлу

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

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

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

Обновлен zip-файл

Перед установкой пакета jszip

npm install jszip --save

А это код, добавьте кодировка: ноль при запросе:

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 } } }
0 голосов
/ 17 декабря 2018

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

  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;у него тот же формат запроса, но вы можете отказаться от обратных вызовов и использовать обещания вместо этого, что считается идиоматическим и будет легче в долгосрочной перспективе.)

...