【问题标题】:How to upload a JPG on to AWS Lambda (NodeJS)如何将 JPG 上传到 AWS Lambda (NodeJS)
【发布时间】:2019-02-26 09:54:46
【问题描述】:

我正在尝试这样做:

  1. 前端:使用<input type="file"><input type="button" onClick="..."> 设置要上传的文件
  2. 使用file[0]<input type="file"> 的值中检索文件对象。
  3. 使用 Javascript Fetch api 调用我的 AWS API-Gateway Post API。

我在请求中尝试了multipart/form-dataapplication/json

  1. 在 AWS Lambda 上,我使用了 Buffer Object 来消耗 body。

我尝试过使用Buffer(body, "utf8")Buffer(body, "base64")Buffer(body, "binary")

  1. 这反过来又被推送到S3 以使用putObject 进行存储。

问题:

  • S3 中设置的文件对象的文件大小为 0 或某个随机值与原始文件大小不匹配。

  • 无法打开从S3下载的文件。

失败的方法

我考虑过multermultiparty。这些似乎是 ExpressJS 中间件,并期望 HttpRequest 对象作为输入(这没有明确提及。似乎我很无知,不能假设这些只能与 HttpRequest 对象一起使用,我花了同时找出答案)。我也很无知,不知道如何将 AWS 事件对象转换为 HttpRequest 对象。不过话虽如此,仅仅为了管理文件上传而使用 Express 引擎似乎有些过分。

将我的S3 存储桶暴露为public-read-write 似乎相当不安全。所以我不考虑前端直接将东西移入/移出我的S3 存储桶。

我的请求

谁能告诉我如何让它工作?和/或这种方法的替代方法?

【问题讨论】:

    标签: node.js amazon-web-services amazon-s3 file-upload aws-lambda


    【解决方案1】:

    这对我有用:

    前端

    • 专门将File 对象编码为base64 字符串。 (How to convert file to base64 in JavaScript?)

    • 检查文件的编码字符串日期,你会发现它有一个;分隔的标头。这也没有在任何地方明确提及。使用.split().join() 删除标题。

    • 现在您可以以任何您想要的形式编写请求。我采取了简单的方法并使用了 JSON。

    • 下面是我提到的一些代码:

      const getBase64fromFile = (file) => {
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = () => {
            console.log(`getBase64fromFile success.`);
            const spliced = reader.result.split(',');
            const header = spliced[0];
            spliced.shift();
            resolve({
              header: header,
              body: spliced.join('')
            });
          };
          reader.onerror = (err) => {
            console.log(`getBase64fromFile failed.`);
            reject(err);
          };
        });
      }
      
      uploadHandler() { 
        console.log(this.state.selectedFile);
      
      const selectedFile = this.state.selectedFile;
      const email = this.state.email;
      return getBase64fromFile(selectedFile)
      .then((base64Data) => {
        return {
          name: selectedFile.name,
          header: base64Data.header,
          base64: base64Data.body,
          email: email
        }
      })
      .then((body) => {
        console.log(`${JSON.stringify(body)}`);
        return body;
      })
      .then((body) => {
        this.setState({status: "Begin uploading..."});
        return fetch(this.state.url+"/upload",
        { // Your POST endpoint
          method: 'POST',
          headers: {
            "Authorization": "Bearer " + this.state.token,
            "x-api-key": this.state.apikey,
            "Accept": "application/json",
          }, 
          body: JSON.stringify(body)
        });
      })
      .then(
        response => response.json() // if the response is a JSON object
      )
      .then(
        success => {
          console.log(success); // Handle the success response object
          this.setState({
            status: success.message
          });
        }
      )
      .catch(
        error => {console.log(error) ;// Handle the error response object
          this.setState({
            status: JSON.stringify(error)
          });
        })
      ;
      }
      

    (https://github.com/flameoftheforest/yaUserMan/blob/master/Tests/frontend/src/App.js)

    AWS-Lambda

    • 现在我们知道数据是以 base64 字符串形式传入的,使用 Buffer.from(body, "base64") 将其转换为八位字节。

    • Buffer.from() 的输出是putObject 需要的<binary string>

    • 下面是我提到的一些代码:

      const params = {
        Bucket: process.env.IMAGE_BUCKET,
        Key: uuid() + event.body.name,
        Body: Buffer.from(event.body.base64, 'base64'),
        ACL: "public-read"
      };
      

    (https://github.com/flameoftheforest/yaUserMan/blob/master/yaUserMan/file2S3Helper.js)

    参考:https://medium.com/@olotintemitope/how-to-upload-files-to-amazon-s3-using-nodejs-lambda-and-api-gateway-bae665127907

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 1970-01-01
      • 2020-10-20
      • 2016-03-23
      • 2019-07-28
      • 2020-09-03
      • 2017-09-04
      • 2018-07-12
      • 2021-01-19
      相关资源
      最近更新 更多