我在nodejs中编写了一个lambda函数,用于将图像上传到S3存储桶。
在我的第一个lambda函数中,我编写了该内联代码(直接在AWS Lambda编辑器中),并且运行良好。相关代码为:
let decodedImage = Buffer.from(encodedImage, 'base64');
console.log(decodedImage);
console.log(typeof decodedImage);
console.log(Object.prototype.toString.call(decodedImage));
try {
await writeToBucket(decodedImage, 'test.png', 'image/png');
} catch (err) {
console.log(err);
}
async function writeToBucket(data, dbFileId, mimeType) {
return new Promise((resolve, reject) => {
var s3 = new AWS.S3();
const params = {
Bucket : S3_BUCKET,
Key : dbFileId,
Body : data,
ACL: 'public-read',
ContentType: mimeType
}
s3.putObject(params, function(err, dataString) {
if (err) {
reject([503, err]);
} else {
resolve();
}
});
});
这三个日志给出:
<Buffer 89 50 4e 47 ... >
object
[object UInt8Array]
因此,如前所述,上述方法工作正常,并且图像已写入存储桶。
现在,我有了第二个Lambda函数,我可以在本地编写该函数,并在使用Webpack构建,压缩和上传后将其上传到Lambda。两个lambda中的代码相同(如上所述),并且控制台输出也相同。但是在第二种情况下,上传失败,并出现以下错误:
{ NetworkingError: The "chunk" argument must be one of type string or Buffer. Received type object
at ClientRequest.end (_http_outgoing.js:690:13)
at features.constructor.writeBody (/var/runtime/node_modules/aws-sdk/lib/http/node.js:137:14)
at features.constructor.handleRequest (/var/runtime/node_modules/aws-sdk/lib/http/node.js:105:12)
at executeSend (/var/runtime/node_modules/aws-sdk/lib/event_listeners.js:342:29)
at Request.SEND (/var/runtime/node_modules/aws-sdk/lib/event_listeners.js:356:9)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:102:18)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
message:
'The "chunk" argument must be one of type string or Buffer. Received type object',
code: 'NetworkingError',
region: 'eu-west-1',
hostname: 's3.eu-west-1.amazonaws.com',
retryable: true,
time: 2019-08-26T14:25:23.006Z }
据我所知,Body负载确实是Buffer类型,我不知道有什么区别?是Webpack(或Babel)搞砸了吗?还是可以与Nodejs.Buffer有关?我在两个Lambda中都运行Node.js10.x。
我的Webpack设置是这样的:
const path = require('path');
require("@babel/register");
require("@babel/plugin-transform-runtime");
const config = {
mode: 'development',
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
library: 'index',
libraryTarget: 'commonjs2'
},
// Loaders
module: {
rules : [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" },
{ test: /\.css$/, use: ['style-loader', 'css-loader']}
]
},
// Plugins
plugins: [],
optimization:{
minimize: false
},
externals: {
'aws-sdk': 'aws-sdk'
}
};
// Exports
module.exports = config;
和package.json依赖项:
"dependencies": {
"@babel/register": "~7.5.5",
"@babel/runtime": "~7.5.5",
"ajv": "~6.10.2",
"ajv-errors": "~1.0.1",
"css-loader": "~3.2.0",
"style-loader": "~1.0.0",
"uuid": "~3.3.3"
},
"devDependencies": {
"@babel/cli": "~7.5.5",
"@babel/core": "~7.5.5",
"@babel/node": "~7.5.5",
"@babel/plugin-transform-runtime": "~7.5.5",
"@babel/preset-env": "~7.5.5",
"aws-sdk": "~2.517.0",
"babel-loader": "~8.0.6",
"cross-var-no-babel": "~1.2.0",
"mocha": "^6.1.4",
"webpack": "~4.33.0",
"webpack-cli": "~3.3"
}
答案 0 :(得分:1)
此错误令人困惑,因为您的代码确实使用Buffer
作为Body
,并且没有可见的chunk
参数,因此该参数必须在SDK内部。孤立地假设,SDK无法正确处理某些东西,并且抛出异常的时间比预期的要晚得多(例如,不是由于调用s3.putObject()
导致的直接结果,而是稍后,在实际的“工作”已经开始。
我有一个na的想法,当尝试优化AWS SDK的大小以进行分发时,我读到了某个关于AWS开发工具包问题的信息……但是我找不到我想要的东西,加上您在{{1 }},所以也许是无关的。
但是我确实找到了 AWS SDK for JavaScript开发者指南(适用于SDK v2)中的Bundling Applications with Webpack:
您可以使用webpack通过将其指定为配置中的目标来生成在Node.js中运行的包。
externals
webpack文档提到了此"...will compile for usage in a Node.js-like environment (uses Node.js require
to load chunks and not touch any built in modules like fs
or path
)"。对于我来说,是否很明显,如果此解释包含一个隐藏的块,说明为什么不包括它会破坏SDK,或者是否发生了其他事情……但指定这似乎是解决问题的原因。
如果我要推测的话,我的猜测是这可以通过禁止包含target: "node"
polyfill来实现,而该填充是由webpack添加的。