【问题标题】:Send file in memory to API from Node Express从 Node Express 将内存中的文件发送到 API
【发布时间】:2017-10-30 13:32:40
【问题描述】:

我在 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);
  });
}

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

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

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

然后用file: bufferStream 在formData 中传递它,但也不起作用。

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

【问题讨论】:

    标签: node.js express file-upload multer


    【解决方案1】:

    我最近遇到了类似的情况,我的过程:web to node to PHP.我用“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)})
        })
    

    【讨论】:

    • 这个 sn-p 拯救了我的一天。
    【解决方案2】:

    我曾多次遇到同样的问题,但总是以糟糕的解决方案告终。谢谢大家的这篇文章。 这是我使用 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)
    

    【讨论】:

      【解决方案3】:
      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));
      }
      

      【讨论】:

      • 我收到一个错误。我需要一些特殊的标题或其他东西吗?在回复中我可以看到"error": "Bad Request", "options": { "method":"POST", "uri": "....", "file": "cHJ1ZWJh=="}
      • 检查您正在调用的 API。他们可能希望请求以某种方式完成。
      • 没什么特别的。如果我使用 Postman 并使用表单数据和文件作为文件发送 POST 请求,API 工作正常。当我检查请求有效负载时,我得到文件的 Content-Type: text/plain,但如果我使用上述机制,它是一个二进制对象,所以我猜有些事情不太正确,API 不知道如何解释这个
      • 当您使用 base64 编码时,您发送的是纯文本,而不是二进制数据。如果你不使用 base64 编码会发生什么?
      • 如果我不使用 base64,那么这就是我在请求标头 "form": { ... "file": { "type": "Buffer", "data": [ 112, 114, 117, 101,... ]}}" 中看到的内容以及来自 API 的相同错误
      【解决方案4】:

      这应该可以解决您的问题

      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);
      };
      

      【讨论】:

        【解决方案5】:

        使用节点内存流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());
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-05
          • 1970-01-01
          • 2017-11-23
          • 2019-08-24
          • 2015-09-15
          • 1970-01-01
          • 2023-03-30
          相关资源
          最近更新 更多