gpt4 book ai didi

node.js - 使用 Node.js 和 Busboy 将多个文件上传到 S3

转载 作者:行者123 更新时间:2023-12-04 13:17:07 25 4
gpt4 key购买 nike

我正在尝试实现一个允许多个文件上传的 API 端点。

我不想将任何文件写入磁盘,而是要缓冲它们并通过管道传输到 S3。

这是我上传单个文件的代码。一旦我尝试将多个文件发布到 route.js 中的端点,它不起作用。
route.js - 我会尽可能保持框架不可知

import Busboy from 'busboy'
// or const Busboy = require('busboy')

const parseForm = async req => {
return new Promise((resolve, reject) => {
const form = new Busboy({ headers: req.headers })
let chunks = []
form.on('file', (field, file, filename, enc, mime) => {
file.on('data', data => {
chunks.push(data)
})
})
form.on('error', err => {
reject(err)
})
form.on('finish', () => {
const buf = Buffer.concat(chunks)
resolve({
fileBuffer: buf,
fileType: mime,
fileName: filename,
fileEnc: enc,
})
})
req.pipe(form)
})
}

export default async (req, res) => {
// or module.exports = async (req, res) => {
try {
const { fileBuffer, ...fileParams } = await parseForm(req)
const result = uploadFile(fileBuffer, fileParams)
res.status(200).json({ success: true, fileUrl: result.Location })
} catch (err) {
console.error(err)
res.status(500).json({ success: false, error: err.message })
}
}
upload.js
import S3 from 'aws-sdk/clients/s3'
// or const S3 = require('aws-sdk/clients/s3')

export default (buffer, fileParams) => {
// or module.exports = (buffer, fileParams) => {
const params = {
Bucket: 'my-s3-bucket',
Key: fileParams.fileName,
Body: buffer,
ContentType: fileParams.fileType,
ContentEncoding: fileParams.fileEnc,
}
return s3.upload(params).promise()
}

最佳答案

我找不到很多相关文档,但我想我已经拼凑了一个解决方案。

大多数实现似乎在将文件上传到 S3 之前将文件写入磁盘,但我希望能够缓冲文件并上传到 S3,而无需写入磁盘。

我创建了这个可以处理单个文件上传的实现,但是当我尝试提供多个文件时,它将缓冲区合并到一个文件中。

我似乎无法克服的一个限制是字段名称。例如,您可以设置 FormData()像这样:

const formData = new FormData()
fileData.append('file[]', form.firstFile[0])
fileData.append('file[]', form.secondFile[0])
fileData.append('file[]', form.thirdFile[0])

await fetch('/api/upload', {
method: 'POST',
body: formData,
}

此结构在 FormData.append() MDN example 中进行了布局。 .但是,我不确定如何处理它。最后,我设置了 FormData()像这样:

表单数据

const formData = new FormData()
fileData.append('file1', form.firstFile[0])
fileData.append('file2', form.secondFile[0])
fileData.append('file3', form.thirdFile[0])

await fetch('/api/upload', {
method: 'POST',
body: formData,
}

据我所知,这并没有明显错误,但这不是首选方法。

这是我更新的代码
route.js
import Busboy from 'busboy'
// or const Busboy = require('busboy')

const parseForm = async req => {
return new Promise((resolve, reject) => {
const form = new Busboy({ headers: req.headers })
const files = [] // create an empty array to hold the processed files
const buffers = {} // create an empty object to contain the buffers
form.on('file', (field, file, filename, enc, mime) => {
buffers[field] = [] // add a new key to the buffers object
file.on('data', data => {
buffers[field].push(data)
})
file.on('end', () => {
files.push({
fileBuffer: Buffer.concat(buffers[field]),
fileType: mime,
fileName: filename,
fileEnc: enc,
})
})
})
form.on('error', err => {
reject(err)
})
form.on('finish', () => {
resolve(files)
})
req.pipe(form) // pipe the request to the form handler
})
}

export default async (req, res) => {
// or module.exports = async (req, res) => {
try {
const files = await parseForm(req)
const fileUrls = []
for (const file of files) {
const { fileBuffer, ...fileParams } = file
const result = uploadFile(fileBuffer, fileParams)
urls.push({ filename: result.key, url: result.Location })
}
res.status(200).json({ success: true, fileUrls: urls })
} catch (err) {
console.error(err)
res.status(500).json({ success: false, error: err.message })
}
}
upload.js
import S3 from 'aws-sdk/clients/s3'
// or const S3 = require('aws-sdk/clients/s3')

export default (buffer, fileParams) => {
// or module.exports = (buffer, fileParams) => {
const params = {
Bucket: 'my-s3-bucket',
Key: fileParams.fileName,
Body: buffer,
ContentType: fileParams.fileType,
ContentEncoding: fileParams.fileEnc,
}
return s3.upload(params).promise()
}

关于node.js - 使用 Node.js 和 Busboy 将多个文件上传到 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59295384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com