简体   繁体   English

如何将多部分文件流从 fastify-multipart 转发到第三部分 api?

[英]How can I forward a mulitpart file stream from fastify-multipart to a 3rd part api?

I have a node api that I'm building that's capable of handling uploads of multipart file types (chunks).我有一个正在构建的节点 api,它能够处理多部分文件类型(块)的上传。 This api is based on the Fastify library, and I've already installed the separate Fastify-Multipart library.这个api是基于Fastify库的,我已经安装了单独的Fastify-Multipart库。 I've got everything working, including mulitpart file uploads, but part of the requirements of this api is to be able to send requests to another api.我已经完成了所有工作,包括多部分文件上传,但是这个 api 的部分要求是能够向另一个 api 发送请求。 In particular, I need to send the file uploads.特别是,我需要发送文件上传。 I don't know what their api is written in, but their multipart file upload api is basically like this:不知道他们的api是怎么写的,但是他们的multipart file upload api基本上是这样的:

sdk.files.uploader(location_id, file_size, "filename.jpg", file)
.then(uploader => uploader.start())
.then(file => { console.log(file) })

My code is basically this:我的代码基本上是这样的:

post: async (request, reply) => {

        // Check for file upload
        if((request.headers['content-type'] && request.headers['content-type'].indexOf('multipart/form-data') !== -1) && request.params.id) {

            const multipart = request.multipart(async (field, stream, filename, encoding, mimetype) => {

                console.log(`folderId: ${request.params.id} filename: ${filename}, 
                            field name: ${field}, encoding: ${encoding}, 
                            mime type: ${mimetype}, file length: ${request.headers['content-length']}`)

                try {
                    let uploader = await sdk.files.uploader(request.params.id, Number(request.headers['content-length']), filename, stream)
                    let file = await uploader.start()
                    console.log(file) //Never reaches this point
                }
                catch(e) {
                    console.log(`An error occurred during upload: ${e.message}`)
                    reply.code(500).send()
                }
                //pump(file, fs.createWriteStream(filename))

            }, (error) => {

                if(error) {
                    console.log(`Error uploading file: ${error.message}`)
                    reply.code(500).send()
                } else {
                    console.log('File upload succeeded') //Upload succeeds but it's just in memory
                    reply.code(201).send()
                }
            })

            multipart.on('field', (key, value) => {
                console.log('form-data', key, value)
            })
        }
    }

So basically what I want to do is pass a multipart file stream to this 3rd party api, but doing it this way doesn't seem to be working (when I go on their site, I don't see the file in the folder where it should be).所以基本上我想要做的是将多部分文件流传递给这个 3rd 方 api,但这样做似乎不起作用(当我访问他们的网站时,我没有在文件夹中看到文件它应该是)。 When I look at Activity Monitor on my machine (macOS), I see the node process is consuming 1.2 Gig of memory (roughly the size of the file).当我在我的机器 (macOS) 上查看活动监视器时,我看到节点进程消耗了 1.2 Gig 的内存(大约是文件的大小)。 Does anyone know a way to do this using Fastify-Multipart (which I believe is based on BusBoy).有谁知道使用 Fastify-Multipart(我相信它基于 BusBoy)来做到这一点的方法。

I notice that your handler post: async (request, reply) => is async, but you are not calling await , but you are managing the reply in the multipart callback.我注意到您的处理程序post: async (request, reply) =>是异步的,但您没有调用await ,而是在多部分回调中管理reply This can cause issues.这可能会导致问题。 Read the promise resolution doc for details. 阅读承诺解决文档以获取详细信息。

I would suggest to check the module you are piping the stream since it must use the steam approach and don't save all the chunks to memory.我建议检查您正在传输流的模块,因为它必须使用steam方法并且不要将所有块保存到内存中。

Here a simple example:这里有一个简单的例子:

const fastify = require('fastify')({ logger: true })
const pump = require('pump')

fastify.register(require('fastify-multipart'))

fastify.post('/', function (req, reply) { // this function must not be async
  if (!req.isMultipart()) { // you can use this decorator instead of checking headers
    reply.code(400).send(new Error('Request is not multipart'))
    return
  }

  const mp = req.multipart(handler, onEnd)

  mp.on('field', function (key, value) {
    console.log('form-data', key, value)
  })

  function onEnd (err) {
    if (err) {
      reply.send(err)
      return
    }
    console.log('upload completed')
    reply.code(200).send()
  }

  async function handler (field, file, filename, encoding, mimetype) {
    console.log('.....waiting')
    await wait() // testing async function
    pump(file, ConsoleWriter({ highWaterMark: 1000 }))
  }
})

fastify.listen(3000)

function wait () {
  return new Promise(resolve => {
    setTimeout(resolve, 1000)
  })
}

// A writer that manage the bytes
const { Writable } = require('stream')
function ConsoleWriter (opts) {
  return new Writable({
    ...opts,
    write (chunk, encoding, done) {
      console.log({ chunk: chunk.length, encoding })
      setTimeout(done, 500) // slow simulation
    }
  })
}

Call it with:调用它:

curl -F file=@"./README.md" -H 'content-type: multipart/form-data' -X POST http://localhost:3000/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何使用websocket使我保持第三方api中的实时数据更新 - How can i use websocket to keep me updated with the live data which is in 3rd party api 使用 Next 或 Node 转发第 3 方 API 响应的正确方法? - Proper way to forward 3rd party API response with Next or Node? 通过 Nodejs API 将 txt 文件从 React 发送到第 3 方 - Sending txt file from React to 3rd party via Nodejs API 如何在 fastify 中使用自定义记录器? - How can i use custom logger in fastify? 我需要帮助尝试通过节点服务器的身份验证调用 3rd 方 api - I need help trying to call 3rd party api with authentication from node server 如何从Node(server.js)调用Gandi.Net之类的第三方API - How to call 3rd party api like Gandi.Net from Node (server.js) 如何向第三方API写入Node.js请求? - How do I write a Node.js request to 3rd party API? Microsoft Bot Framework-如何从第三方API发送响应 - Microsoft Bot Framework - how to send responses from a 3rd party API 我应该在后端还是前端进行 3rd 方 API 调用? - Should I make 3rd party API calls in backend or frontend? 如何将 fastify swagger api 描述保存到本地文件 - How to save fastify swagger api description to local file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM