【问题标题】:The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined第一个参数必须是字符串类型或 Buffer、ArrayBuffer 或 Array 或类数组对象的实例。收到未定义
【发布时间】:2022-02-06 20:47:51
【问题描述】:

我正在尝试通过触发 Postman 的请求,使用用 NodeJS 编写的 Lambda 函数上传文件 (pdf/jpg),但出现以下错误:-

2022-02-02T15:09:51.135Z    743939db-7511-4003-8e49-40c95ada47b4    ERROR   Invoke Error    
{
    "errorType": "TypeError",
    "errorMessage": "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined",
    "code": "ERR_INVALID_ARG_TYPE",
    "stack": [
        "TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined",
        "    at new NodeError (internal/errors.js:322:7)",
        "    at Function.from (buffer.js:334:9)",
        "    at Runtime.exports.lambdaHandler [as handler] (/var/task/app.js:68:23)"
    ]
}

以下是 CloudWatch 上记录的事件对象块:-

2022-02-02T20:39:52.136+05:30

Copy
info: Event:: {"body":"{\n    \"base64String\": \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAcHBwcIBwgJCQgMDAsMDBEQDg4QERoSFBIUEhonGB0YGB0YJyMqIiAiKiM+MSsrMT5IPDk8SFdOTldtaG2Pj8ABBwcHBwgHCAkJCAwMCwwMERAODhARGhIUEhQSGicYHRgYHRgnIyoiICIqIz4xKysxPkg8OTxIV05OV21obY+PwP/CABEICHAPAAMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAABwgBBQYEAwL/2gAIAQEAAAAAsiAA

Lambda(NodeJS 代码):-

'use-strict'

const AWS = require("aws-sdk");

const logger = require('./logger').logger;

const moment = require('moment');

const fileType = ('file-type');

const { Buffer } = require('buffer');

//const { fileTypeFromFile } = 'file-type';

const ddbTable = process.env.RUNTIME_DDB_TABLE_FREE_USER_DOCUMENT;

const s3TempBucket = process.env.RUNTIME_S3_TEMP_BUCKET;

const s3 = new AWS.S3();

const getFile = (fileMime, buffer, userId) => {
  let fileExt = fileMime.ext;
  let hash = sha1(new Buffer(new Date().toString()));
  let now = moment().format('YYYY-MM-DD HH:mm:ss');

  let filePath = hash + '/';
  let fileName = unixTime(now) + '.' + fileExt;
  let fileFullName = filePath + fileName;
  let fileFullPath = s3TempBucket + userId + fileFullName;

  const params = {
    Body: buffer,
    Bucket: s3TempBucket,
    Key: fileName
  };

  let uploadFile = {
    size: buffer.toString('ascii').length,
    type: fileMime.mime,
    name: fileName,
    fullPath: fileFullPath
  }

  return {
    'params': params,
    'uploadFile': uploadFile
  }
}

exports.lambdaHandler = async (event, context) => {
  logger.info("Event::", event);
  logger.info('Uploading file to bucket::', s3TempBucket);

  let body, data;
  let statusCode = 200;
  const headers = {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Headers': 'Content-Type',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': '*'
  };

  let request = JSON.parse(event.body);
  let base64String = await request.base64String;
  logger.info("base64String::", base64String);

  let buffer = Buffer.from(base64String, 'base64');

  //let buffer = new Buffer(base64String, 'base64');
  let fileMime = fileType(buffer);
  logger.info(fileMime);

  if (fileMime === null) {
    return context.fail('String supplied is not file type');
  }

  //let file = getFile(fileMime, buffer, user.id);
  let file = getFile(fileMime, buffer, 'b06eb6f4-0ff0-5cb5-a41c-e000af66c8e9');
  let params = file.params;

  try {
    //await new Promise((resolve, reject) => {
      s3.putObject(params, (err, results) => {
        if (err) reject(err);
        else {
          console.log(results);
          body = results;
          resolve(results)
        }
      });
   // });

  } catch (err) {
    logger.info(err);
    statusCode = 400;
    body = err.message;
    return err;
  } finally {
    body = JSON.stringify(data);
  }

  return {
    statusCode,
    body,
    headers
  };

}

base64String 是未定义的,不知道为什么我可以在事件对象中清楚地看到?:-

let buffer = Buffer.from(base64String, 'base64');

请帮忙,谢谢

邮递员请求:-

【问题讨论】:

  • 这可能会有所帮助。 stackoverflow.com/questions/13807339/…
  • @shimo 我已经通过该链接并尝试尝试它,但该解决方案将无法正常工作,因为它需要像 express 这样的中间件,但我正在寻找一个纯基于 Lambda 的解决方案......我进行了很多研究,但过去 3 周在网络上没有找到单一的解决方案,可以让基于 NodeJS 的 Lambda 上传文件......老实说,我真的很沮丧
  • 很抱歉。我发布了一个使用 Lambda 存储库示例的答案。无论如何它都有效。

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


【解决方案1】:

如果您使用 API Gateway,您不需要 base64 编码,因为 API Gateway 会自动进行

AWS 中提供了一个示例。

  1. 选择创建函数
  2. 选择浏览无服务器应用程序存储库
  3. 找到“上传器:用于将文件上传到的无服务器 Web 应用程序 S3"
  4. 部署

uploader's github

这将创建 API 网关和 NodeJS Lambda。 (您需要提供 S3 存储桶。)

说明要上传文件,在浏览器中打开 InvokeURL 并拖放文件。您也可以使用 Postman 执行此操作,如下所示。

  1. 输入POST InvokeURL/api/file/text.pdf
  2. 将正文 KEY 设置为 File 并输入 text.pdf。选择 pdf 文件作为 VALUE。
  3. 发送

您可以在 index.js 中找到代码并提取您需要的内容。

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2021-06-10
    • 2021-08-07
    • 2022-01-21
    • 2020-11-02
    • 2020-12-09
    相关资源
    最近更新 更多