Aus*_*met 3 javascript amazon-s3 amazon-web-services node.js aws-lambda
因此,我正在编写一个 Lambda,它将通过 API Gateway 直接 POST 获取某种表单数据(目前使用 Postman 进行测试),然后将该图像发送到 S3 进行存储。每次运行它时,上传到 S3 的图像都会损坏并且无法正常打开。我见过人们必须对传入数据进行解码/编码,但我觉得我已经尝试了使用Buffer.from. 我只想存储.png或.jpg。下面的代码并不反映我使用 Base64 编码/解码的尝试,因为它们都失败了。这是我到目前为止所拥有的 -
邮递员中的示例请求
{
image: (uploaded .jpg/.png),
metadata: {tag: 'iPhone'}
}
Run Code Online (Sandbox Code Playgroud)
拉姆达
const AWS = require('aws-sdk')
const multipart = require('aws-lambda-multipart-parser')
const s3 = new AWS.S3();
exports.handler = async (event) => {
const form = multipart.parse(event, false)
const s3_response = await upload_s3(form)
return {
statusCode: '200',
body: JSON.stringify({ data: data })
}
};
const upload_s3 = async (form) => {
const uniqueId = Math.random().toString(36).substr(2, 9);
const key = `${uniqueId}_${form.image.filename}`
const request = {
Bucket: 'bucket-name',
Key: key,
Body: form.image.content,
ContentType: form.image.contentType,
}
try {
const data = await s3.putObject(request).promise()
return data
} catch (e) {
console.log('Error uploading to S3: ', e)
return e
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我现在尝试将图像保存到/tmp目录中,然后使用读取流上传到 s3。这是一些代码
s3上传功能
const AWS = require('aws-sdk')
const fs = require('fs')
const s3 = new AWS.S3()
module.exports = {
upload: (file) => {
return new Promise((resolve, reject) => {
const key = `${Date.now()}.${file.extension}`
const bodyStream = fs.createReadStream(file.path)
const params = {
Bucket: process.env.S3_BucketName,
Key: key,
Body: bodyStream,
ContentType: file.type
}
s3.upload(params, (err, data) => {
if (err) {
return reject(err)
}
return resolve(data)
}
)
})
}
}
Run Code Online (Sandbox Code Playgroud)
表单解析器函数
const busboy = require('busboy')
module.exports = {
parse: (req, temp) => {
const ctype = req.headers['Content-Type'] || req.headers['content-type']
let parsed_file = {}
return new Promise((resolve) => {
try {
const bb = new busboy({
headers: { 'content-type': ctype },
limits: {
fileSize: 31457280,
files: 1,
}
})
bb.on('file', function (fieldname, file, filename, encoding, mimetype) {
const stream = temp.createWriteStream()
const ext = filename.split('.')[1]
console.log('parser -- ext ', ext)
parsed_file = { name: filename, path: stream.path, f: file, type: mimetype, extension: ext }
file.pipe(stream)
}).on('finish', () => {
resolve(parsed_file)
}).on('error', err => {
console.err(err)
resolve({ err: 'Form data is invalid: parsing error' })
})
if (req.end) {
req.pipe(bb)
} else {
bb.write(req.body, req.isBase64Encoded ? 'base64' : 'binary')
}
return bb.end()
} catch (e) {
console.error(e)
return resolve({ err: 'Form data is invalid: parsing error' })
}
})
}
}
Run Code Online (Sandbox Code Playgroud)
处理程序
const form_parser = require('./form-parser').parse
const s3_upload = require('./s3-upload').upload
const temp = require('temp')
exports.handler = async (event, context) => {
temp.track()
const parsed_file = await form_parser(event, temp)
console.log('index -- parsed form', parsed_file)
const result = await s3_upload(parsed_file)
console.log('index -- s3 result', result)
temp.cleanup()
return {
statusCode: '200',
body: JSON.stringify(result)
}
}
Run Code Online (Sandbox Code Playgroud)
上面编辑的代码是其他代码和我发现的 github 存储库的组合,它试图实现相同的结果。即使使用此解决方案,文件仍然损坏
想通了这个问题。代码工作得很好——这是 API 网关的问题。需要进入 API 网关设置并设置二进制媒体类型,然后multipart/form-data重新部署 API。希望这可以帮助那些正在绞尽脑汁想通过表单数据将图像发送到 lambda 的人。
| 归档时间: |
|
| 查看次数: |
3940 次 |
| 最近记录: |