将内存中的文件从Node Express发送到API

时间:2017-05-30 07:27:00

标签: node.js express file-upload multer

我在Node和Express中有一个API,它从客户端接收文件(开发中的邮递员),我使用multer将文件存入内存,如下所示:

router.post('/api/v1/upload', contrl.upload, contrl.uploadFile);

然后在我的控制器中:

exports upload = multer({ storage: multer.memoryStorage() }).single('file');

现在我可以使用req.file.buffer访问该文件,但之后我想将此文件发送到另一个API。 我正在使用request-promise-native所以这将是这样的:

const rp = require('request-promise-native')

exports.uploadFile = (req, res) => {

  const options = {
    method: 'POST',
    uri: `${uri}`,
    form: {
      file: req.file.buffer
    }
  }

  rp(options)
    .then(parsedBody => {
      return res.status(201).send(parsedBody);
    })
    .catch(err => res.status(400).send(err));
}

为了简单起见,我删除了一些其他参数,但这不起作用,可能是因为Node不知道如何处理req.file.buffer中的信息。

编辑。 在一些测试后,我尝试使用真实文件而不是使用multer memoryStorage。所以我明白了:

exports upload = multer({ dest: 'uploads/' }).single('file');

将文件保存到磁盘,然后

const request = require('request')

exports.uploadFile = (req, res) => {

  const formData = {
    file: fs.createReadStream('uploads/' + req.file.filename)
  }
  const options = {
    url: `${uri}`
    formData
  }

  request.post(options, (err, response, body) => {
    if (err) return res.status(400).send(err);
    return res.status(201).send(response);
  });
}

它的确有效!但是当我在更换时更改为memoryStorage并使用file: req.file.buffer时,它不起作用。

EDIT2: 我还尝试在内存中将文件作为流发送,所以我尝试了这个

const bufferStream = new stream.PassThrough();
bufferStream.end(req.file.buffer);

然后在带有file: bufferStream的formData中传递它,但也无效。

我怎样才能做到这一点? 感谢

5 个答案:

答案 0 :(得分:2)

我最近遇到了类似的情况,我的进程:web到节点到PHP.I使用“multer”和“request”解决了这个问题,我不使用真实文件。

    const multer  = require('multer')
    const upload = multer();
    const request = require('request');

    router.post('/upload', upload.single('img'),(req,res,next) => {

        let formData = {
            'quality':80,
            //file field need set options 'contentType' and 'filename' for formData
            'file':{
                value:req.file.buffer,
                options:{
                    contentType:req.file.mimetype,
                    filename:req.file.originalname
                }
            }
        }    
       request.post({
             url:''/**uploadurl*/,
             formData
       },function(err,response,body){res.send(body)})
    })

答案 1 :(得分:0)

const rp = require('request-promise-native')

exports.uploadFile = (req, res) => {

  const options = {
    method: 'POST',
    uri: `${uri}`,
    formData: {
      file: req.file.buffer
    }
  }

  rp(options)
    .then(parsedBody => {
      return res.status(201).send(parsedBody);
    })
    .catch(err => res.status(400).send(err));
}

答案 2 :(得分:0)

这应该可以解决您的问题

const http = require('http');
exports.uploadFile = (req, res) => {
    // create new request to reupload file
    const request = http.request({  
        port : 80,
        hostname : '127.0.0.1',
        method : 'POST',
        path : '/'
    });
    let result = '';
    // grab response from new request
    request.on('data', (chunk) => {
        result += chunk;
    });
    // resend response from new request
    request.on('end', () => {
        res.status(201).end(result);
    });
    // resend error from new request
    request.on('error', (err) => {
        res.status(400).end(err);
    });
    // pipe your file to new request
    req.file.stream.pipe(request);
};

答案 3 :(得分:0)

使用节点内存流https://www.npmjs.com/package/memory-streams

var streams = require('memory-streams')
  , fs      = require('fs');

// Pipe  
var reader = fs.createReadStream('index.js');
var writer = new streams.WritableStream();
reader.pipe(writer);
reader.on('readable', function() {

  // Output the content as a string 
  console.log(writer.toString());

  // Output the content as a Buffer 
  console.log(writer.toBuffer());
});

答案 4 :(得分:0)

我遇到过几次同样的问题,但总是得到一个糟糕的解决方案。谢谢大家的这篇文章。 这是我的 aixios 解决方案,以防有人可以使用它

//First use form-data
const FormData = require('form-data') ;
//use axios
const axios = require('axios') ;


//Note is very important passing contentType and filename 
//options
let form = new FormData() ;
//consider req.file is the file coming from multer
form.append('file',req.file.buffer,{
     contentType:req.file.mimetype,
     filename:req.file.originalname
  }) ;


//now do a post request with axios
// personally I like the use of async-await for promises but
//then() catch() will work just fine
let response = await axios.post('API_URL', form, {
  headers: form.getHeaders() 
});
// whatever you need with response ex.
console.log(response.data)