В настоящее время я получаю файл, закодированный как строку base64, как часть полезной нагрузки json:

{
    "file":"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPGRlZmluaXRpb25zIHhtb..."
}

С этой строкой я должен отправить файл как multipart / form-data в другую службу, поэтому у меня есть такой метод (используя модуль запроса):

var request = require('request');
var fs = require('fs');

var importFile = function(fileBase64Encoded, cb) {
    var decodedFile = new Buffer(fileBase64Encoded, 'base64');
    var r = request.post('http://localhost:8888/upload', function (err, httpResponse, body) {
        if (err) {
            cb(err);
        }
        cb(null, body);
    });
    var form = r.form();
    form.append('file', decodedFile);
}

И это в настоящее время не работает. Если я запишу файл на диск и прочитаю его оттуда вот так:

var request = require('request');
var fs = require('fs');

var importFile function(fileBase64Encoded, cb) {

    var decodedFile = new Buffer(fileBase64Encoded, 'base64');
    fs.writeFile('temp.txt', decodedFile, function (err) {
        if (err) return console.log(err);
        var r = request.post('http://localhost:8888/upload', function (err, httpResponse, body) {
            if (err) {
                cb(err);
            }
            cb(null, body);
        })
        var form = r.form();
        form.append('file', fs.createReadStream('temp.txt'));
    });

}

Тогда это работает ... Итак, есть ли реальный способ передать строку base64 в качестве допустимого параметра в форму? (сейчас пытаюсь с буфером и не работает)

7
jdrm 26 Авг 2014 в 21:03

1 ответ

Лучший ответ

Я предполагаю, что http://localhost:8888/upload ожидает, что file будет ... "файлом". Когда вы передаете файловый поток в form.append(), он уже знает, что это «файл». При прохождении Buffer этого не происходит.

Однако вы можете указать form.append() интерпретировать ваш Buffer как "файл", передав объект параметров в качестве третьего аргумента. Объект параметров должен иметь ключ с именем filename, содержащий строку с именем файла. При желании объект может также включать строку contentType и целое число knownLength. Если contentType не включен, form.append() попытается получить тип содержимого из filename.

За исключением определения contentType (когда он явно не передан в аргументе параметров), указанный вами filename не имеет значения (т.е. вы можете использовать любое имя файла, какое захотите). Если, конечно, вы не собираетесь использовать filename в коде на стороне сервера.

В вашем случае должно работать следующее.

var importFile = function(fileBase64Encoded, cb) {
    var decodedFile = new Buffer(fileBase64Encoded, 'base64');
    var r = request.post('http://localhost:8888/upload', function (err, httpResponse, body) {
        if (err) {
            cb(err);
        }
        cb(null, body);
    });
    var form = r.form();
    form.append('file', decodedFile, { filename: 'temp.txt' });
}
12
JME 27 Авг 2014 в 03:16
Когда вы вызываете request.post (), уже запущен ли почтовый запрос? Как его запустить после добавления?
 – 
Sisir
31 Окт 2018 в 14:07
... request.post() срабатывает автоматически во время следующего цикла цикла событий. Любые изменения в r (объект запроса) могут быть выполнены до запуска следующего цикла.
 – 
JME
28 Ноя 2018 в 06:19