如何通过multer上传保存在内存中的文件到另一个API

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过multer上传保存在内存中的文件到另一个API相关的知识,希望对你有一定的参考价值。

我有2个独立的NodeJS API,使用multer将文件保存在内存中。

我的快速中间件看起来像这样

import multer from 'multer';
const storage = multer.memoryStorage();

export default multer({ storage }).single('image');

我能够成功接收保存在内存中的文件,所以我的req.file.image看起来像这样

{ 
  fieldname: 'image',
  originalname: 'image-2017-08-28-13-47-31-218.png',
  encoding: '7bit',   mimetype: 'image/png',
  buffer: <Buffer 89 50 4e 47 0d 0a 1a 0 ... >, 
  size: 493181
}

收到文件后,在第一个API上,我需要将它发送到也使用multer&express的第二个API

function secondApiReceiveImage(req, res) {
  console.log(req.file)
  console.log(req.files)
  console.log(req.body)
  res.send('ok');
}

我尝试使用以下实现发送

通过https://github.com/request/request#multipartform-data-multipart-form-uploads

import request from 'request';

function firstApiReceiveImage(req, res) {
  const options = {
    url:'http://SECOND_API/api/image',
    formData: { image: req.file.buffer }
  };
  request.post(options, (err, httpResponse, body) => {
    console.log('err', err);
    console.log('body', body);
  });
}

在这种情况下,req.file,req.files和req.body的日志都是在secondApiReceiveImage API处理函数上未定义的。

我的下一次尝试是与https://github.com/form-data/form-data

import multer from 'multer';
const storage = multer.memoryStorage();

export default multer({ storage }).single('image');

function firstApiReceiveImage(req, res) {
  const CRLF = '\r\n';
  const form = new FormData();
  const opts = {
    header: `${CRLF} + '--' + ${form.getBoundary()} + ${CRLF} + 'X-Custom-Header: 123' + ${CRLF} + ${CRLF}`,
    knownLength: 1
  };

  form.append('image', req.file.image.buffer, opts);
  form.submit('http://SECOND_API/api/image', (err, res) => {
    console.log('err', err);
    console.log('res', res);
  });
}

我得到了相同的结果,未定义的第二个API上的req.file,req.files和req.body

除了multer BTW之外,这些是我的两个API的中间件

app.use(compression());
app.use(helmet());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

如果我可以在第一个API上保存文件,我本可以过上更轻松的生活,但在这种情况下我们不允许保存到磁盘:(

对我有什么建议吗?

答案

使用Request,formdata应设置为缓冲区:

formData: { image: req.file.buffer }
另一答案

通过将缓冲区转换为Stream并以不同方式发送表单数据,团队能够完成此操作。

import stream from 'stream';
import rq from 'request-promise';

const { Duplex } = stream;

function bufferToStream(buffer) {
  const duplexStream = new Duplex();
  duplexStream.push(buffer);
  duplexStream.push(null);
  return duplexStream;
}

async function store({
  originalname, mimetype, size, buffer,
}) {
  logger.debug(`Saving image name:${originalname} type:${mimetype} size:${size}`);

  const formData = {
    image: {
      value: bufferToStream(buffer),
      options: {
        filename: originalname,
        contentType: mimetype,
        knownLength: size,
      },
    },
  };

  const options = Object.assign({}, IMAGE_SAVE_ENDPOINT, { formData });
  const response = await rq(options);
  return response.id;
}

以上是关于如何通过multer上传保存在内存中的文件到另一个API的主要内容,如果未能解决你的问题,请参考以下文章

使用 Multer 上传文件并在解析和上传到数据库之前将其短暂存储在内存中

如何在 formData 对象中附加文件而不在 Node.js 中物理保存文件?

使用带有 expressjs 的 multer 上传文件时的错误处理

nodejs multer diskstorage在保存到磁盘后删除文件

如何在节点中使用 multer 将图像上传到 cloudinary 并与其他数据一起表达

使用 fs 在 multer 中重命名上传的图像