在 Lambda 中使用 multipart/form-data
Working with multipart/form-data in Lambda
我有一个从 AWS API 网关调用的 lambda 函数。
lambda 正在接收图像作为 multipart/form-data 然后 lambda 需要添加一些额外的 headers 并将该图像传递给另一个外部服务也使用 multipart/form-data。
现在,我的服务是这样做的:
'use strict'
const AWS = require('aws-sdk');
const https = require('https');
const request = require('request');
exports.handler = (event, context, callback) => {
const options = {
method: 'POST',
url: 'https://external-service/image-storage',
port: 443,
headers: {
"Content-Type": "multipart/form-data"
},
formData: {
username: "67a43djte5s4cb54mnasbds23",
secret: "47938hjfsdhjfdfdfs",
photo: \ I want to put here the image received in the event
}
};
request(options, function(err, res, body) {
if (err) console.log(err);
console.log(body);
});
}
在 photo
参数中我尝试输入 event.body
但它不起作用,因为外部服务给了我一个 "invalid request" (我已经尝试过外部服务邮递员,它工作正常)。
所以我认为问题出在 lambda 上。
当我在控制台打印 event.body
的内容时,这是输出:
2020-04-02T13:17:27.478Z 0c03qsrf-78a2-2356-b9b0-0fd76fb367712 INFO ----------------------------027326659651005153655343
Content-Disposition: form-data; name="image"; filename="MyImage.jpg"
Content-Type: image/jpeg
����JFIF��C...
我是否需要对 body 进行任何额外的转换?
谢谢,
以防万一有人来到这里遇到我昨天遇到的同样问题,最好的方法是遵循 Michael Hausenblas 的建议(请参阅他在我的问题下的评论)并使用 S3 和预签名网址。
但是,由于我的前端存在一些限制,我无法采用这种方法。
最后,我不得不将 API 输入从 multipart/form-data 内容类型替换为 application/json 并将 JSON 对象中以 base64 编码的图像从我的前端发送到我的 lambda。然后从 lambda 构建外部服务的多部分对象:
'use strict'
const AWS = require('aws-sdk');
const request = require('request');
exports.handler = (event, context, callback) => {
let json_body = JSON.parse(event.body)
var base64image = json_body.image;
base64image = base64image.replace('data:image/jpeg;base64,', '');
request({
url: 'https://external-service/image-storage',
method: 'POST',
formData: {
'username': '67a43djte5s4cb54mnasbds23',
'secret': '47938hjfsdhjfdfdfs',
'image': {
value: Buffer.from(base64image, 'base64'),
options: {
filename: 'photo1.jpg',
contentType: 'image/jpeg'
}
}
}
}, function (err,resp,body){
if(err){
console.log("Error");
}else{
console.log("Response" + body);
}
});
}
正如我所说,我建议采用预签名 url 方法,但我提供了这种替代方法,以防您的前端也有限制。
我有一个从 AWS API 网关调用的 lambda 函数。
lambda 正在接收图像作为 multipart/form-data 然后 lambda 需要添加一些额外的 headers 并将该图像传递给另一个外部服务也使用 multipart/form-data。
现在,我的服务是这样做的:
'use strict'
const AWS = require('aws-sdk');
const https = require('https');
const request = require('request');
exports.handler = (event, context, callback) => {
const options = {
method: 'POST',
url: 'https://external-service/image-storage',
port: 443,
headers: {
"Content-Type": "multipart/form-data"
},
formData: {
username: "67a43djte5s4cb54mnasbds23",
secret: "47938hjfsdhjfdfdfs",
photo: \ I want to put here the image received in the event
}
};
request(options, function(err, res, body) {
if (err) console.log(err);
console.log(body);
});
}
在 photo
参数中我尝试输入 event.body
但它不起作用,因为外部服务给了我一个 "invalid request" (我已经尝试过外部服务邮递员,它工作正常)。
所以我认为问题出在 lambda 上。
当我在控制台打印 event.body
的内容时,这是输出:
2020-04-02T13:17:27.478Z 0c03qsrf-78a2-2356-b9b0-0fd76fb367712 INFO ----------------------------027326659651005153655343
Content-Disposition: form-data; name="image"; filename="MyImage.jpg"
Content-Type: image/jpeg
����JFIF��C...
我是否需要对 body 进行任何额外的转换?
谢谢,
以防万一有人来到这里遇到我昨天遇到的同样问题,最好的方法是遵循 Michael Hausenblas 的建议(请参阅他在我的问题下的评论)并使用 S3 和预签名网址。
但是,由于我的前端存在一些限制,我无法采用这种方法。
最后,我不得不将 API 输入从 multipart/form-data 内容类型替换为 application/json 并将 JSON 对象中以 base64 编码的图像从我的前端发送到我的 lambda。然后从 lambda 构建外部服务的多部分对象:
'use strict'
const AWS = require('aws-sdk');
const request = require('request');
exports.handler = (event, context, callback) => {
let json_body = JSON.parse(event.body)
var base64image = json_body.image;
base64image = base64image.replace('data:image/jpeg;base64,', '');
request({
url: 'https://external-service/image-storage',
method: 'POST',
formData: {
'username': '67a43djte5s4cb54mnasbds23',
'secret': '47938hjfsdhjfdfdfs',
'image': {
value: Buffer.from(base64image, 'base64'),
options: {
filename: 'photo1.jpg',
contentType: 'image/jpeg'
}
}
}
}, function (err,resp,body){
if(err){
console.log("Error");
}else{
console.log("Response" + body);
}
});
}
正如我所说,我建议采用预签名 url 方法,但我提供了这种替代方法,以防您的前端也有限制。