【问题标题】:s3.putObject(params).promise() does not upload file, but successfully executes then() callbacks3.putObject(params).promise() 不上传文件,但成功执行 then() 回调
【发布时间】:2020-01-20 17:20:21
【问题描述】:

我曾多次尝试将文件放入 S3 存储桶,之后我必须更新我的模型。

我有以下代码(请注意,我也尝试过注释行。它既不适用于 cmets,也不适用于没有它。)

观察到的问题: 第一个 .then() 块 (successCallBack()) 中的所有内容都已成功执行,但我没有看到 s3.putObject() 的结果。

有问题的存储桶是公开的,没有访问限制。它曾经与 sls 脱机选项一起使用,然后由于它无法在 AWS 中工作,我不得不进行大量更改并设法使 successCallback() 工作,从而使数据库成功工作。但是,文件上传仍然不起作用。

一些问题:

在解决这个问题时,我正在思考/搜索的真正问题是,

  • lambda 是否应该返回一些东西?我看到了 AWS 文档,但他们有零碎的代码 sn-ps。

  • await 放在s3.putObject(params).promise() 前面没有帮助。我在具有 AWS Promise() 函数调用的事物前面看到了带有和不带有 await 的示例。不确定哪些是正确的。

  • 将异步函数链接到一个 lambda 函数中时,正确的方法是什么?

更新:

var myJSON = {}
const createBook = async (event) => {

    let bucketPath = "https://com.xxxx.yyyy.aa-bb-zzzzzz-1.amazonaws.com"
    let fileKey = //file key
    let path = bucketPath + "/" + fileKey;

    myJSON = {
      //JSON from headers
    }

    var s3 = new AWS.S3();
    let buffer = Buffer.from(event.body, 'utf8');

    var params = {Bucket: 'com.xxxx.yyyy', Key: fileKey, Body: buffer, ContentEncoding: 'utf8'};

    let putObjPromise = s3.putObject(params).promise();

    putObjPromise
    .then(successCallBack())
    .then(c => {
      console.log('File upload Success!');
      return {
        statusCode: 200,
        headers: { 'Content-Type': 'text/plain' },
        body: "Success!!!"
      }
    })
    .catch(err => {   
        let str = "File upload /  Creation error:" + err;
        console.log(str);
        return {
          statusCode: err.statusCode || 500,
          headers: { 'Content-Type': 'text/plain' },
          body: str
        }
    });
}

const successCallBack = async () => {
  console.log("Inside success callback - " + JSON.stringify(myJSON))  ;
  const { myModel } = await connectToDatabase()
  console.log("After connectToDatabase")
  const book = await myModel.create(myJSON)

  console.log(msg);
}

【问题讨论】:

  • 你确定putObject() 不工作吗?添加新项目最终将保持一致,因此它可能不会立即出现。大约 20 秒后可能值得仔细检查。
  • 也....您正在调用回调,而不是在代码中引用它。你应该做类似pubObjPromise.then(successCallBack).then( #handle return from successCB)
  • successCallBack() 工作成功,在代码底部定义。我也看到了来自 successCallBack() 的所有日志。我试了一整天,桶还是空的。
  • 传递函数引用successCallBack而不是调用(即successCallBack(params)
  • 我放了 putObjPromise .then(successCallBack) 但它根本没有执行它。日志中没有错误。

标签: amazon-web-services amazon-s3 promise aws-lambda aws-sdk


【解决方案1】:

最后,我得到了这个工作。我的代码已经在 sls 离线设置中工作了。

AWS 端点有什么不同?

我在控制台上观察到的事实是,我的 lambda 设置为在 VPC 下运行。

当我选择 No VPC 时,它起作用了。我不知道这是否是最佳做法。在 VPC 下运行的函数一定会获得一些安全优势。

我遇到了这个巨大的explanation about VPC,但我找不到任何与 S3 相关的东西。

问题中发布的代码目前在 AWS 端点上运行良好。

【讨论】:

    【解决方案2】:

    如果 lambda 在 VPC 中运行,那么您需要一个 VPC 终端节点才能访问该 vpc 之外的服务。 S3 将在 VPC 之外。如果安全是一个问题,那么创建 VPC 端点可能会以更好的方式解决该问题。此外,如果安全是一个问题,那么可能会向 lambda 正在使用的角色添加一个策略(或使用默认的 AmazonS3FullAccess 策略),那么 S3 存储桶就不需要是公共的。

    【讨论】:

    • +1 很好的解释。虽然我的工作正在进行中,但此设置仍然在 Postman 中给我 502 错误。尽管我从所有成功路径中返回 200。 Lambda 不会以某种方式从 then() 块返回我的 JSON。
    • 我没有尝试过以这种方式处理承诺,所以我不确定。就像一个测试可能会尝试等待以查看 lambda 是否在 then() 被执行之前退出。只是一个想法。
    猜你喜欢
    • 1970-01-01
    • 2012-09-09
    • 2021-12-31
    • 2021-05-15
    • 2012-10-05
    • 1970-01-01
    • 2015-08-24
    • 2015-07-28
    • 2021-07-15
    相关资源
    最近更新 更多