【问题标题】:Reading .csv data after uploading via a POST request to an AWS Lambda Node.js function通过 POST 请求上传到 AWS Lambda Node.js 函数后读取 .csv 数据
【发布时间】:2021-12-06 14:43:55
【问题描述】:

我有一个场景,我需要使用 axios 通过 AWS API Gateway 将一个 .csv 文件从一个反应前端上传到一个用 Node.js 编写的 AWS Lambda 函数。从那里我将处理 csv 文件的行并将它们保存到数据库中。

到目前为止,我已经设法使用以下代码将数据导入 lambda 函数:

反应片段

...
 export const upload = async (file: any) => {
  await axios({
    method: "post",
    url: url,
    data: file,
    headers: { "Content-Type": "multipart/form-data" },
  })
    .then(function (response) {
      //handle success
      console.log(response);
      return response;
    })
    .catch(function (response) {
      //handle error
      console.log(response);
      return response;
    });

const upload = async () => {
    setIsLoadng(true);

    if (selectedFile) {
      debugger;
      const formData = new FormData();

      formData.append("File", selectedFile);

      await upload(formData);

      setIsLoadng(false);
    } else {
      setIsLoadng(false);
      alert("Please choose a file to upload.");
    }
  };
...

但它以 base64 编码到达。这就是我从 lambda 函数中提取数据的方式:

AWS Lambda 函数

exports.handler = async (event) => {

  try {
    console.log(`Event: ${JSON.stringify(event)}`);

    // Decoding the base64 encoded body from AWS API Gateway
    let buff = Buffer.from(event.body, "base64");

    console.log(`Buffer data decoded: ${buff}`);

    console.log(`Type: ${typeof buff}`);

    const response = {
      statusCode: 200,
      body: JSON.stringify("Some data here..."),
    };
    return response;
  } catch (err) {
    console.log(err);
    const response = {
      statusCode: 200,
      body: JSON.stringify(err),
    };
    return response;
  }
};

这一切都很好,但是,解码后我似乎无法轻松地将其解析为 JSON 格式进行处理,因为数据被 webkit 表单边界包围:

'------WebKitFormBoundary0YYQOz5kaQyRTGk4
Content-Disposition: form-data; name="File"; filename="file001.csv"
Content-Type: application/vnd.ms-excel
...
the actual .csv data
...
------WebKitFormBoundary0YYQOz5kaQyRTGk4--
'

我认为 axios 已经格式化了我的数据并根据 content-type: multipart/form-data 正确发送了请求。我也相信 AWS API Gateway 将这样的数据编码到 base64 中,这是我在 lambda 函数中收到的。但是,一旦我对数据进行解码,我就会得到这个字符串,其中包含所有标题信息和“------WebKitFormBoundary0YYQOz5kaQyRTGk4”顶部和底部位。

有没有更好的方法来处理 .csv 数据,以便我可以在我的 lambda 函数中有一个很好解析的 JSON 对象来处理。到目前为止,我一直在尝试组合一个字符串“查找和连接”解决方案,但这感觉很不对。

真诚感谢任何帮助或指导!

B

【问题讨论】:

  • “我已经设法将数据导入 lambda 函数” - 显示执行此操作的代码。
  • 你说的是axois函数还是lambda函数里面的代码?
  • 我的意思是导致未解析的请求正文出现在您的 AWS 函数中的代码。您在那里缺少一个处理步骤。
  • 如果有意义的话,我会使用 Buffer 来解码传入的数据...?
  • body 是被编码的,你需要一个叫做 body parser 的东西来整理它。这是一项基本的操作,你只是不这样做。不要尝试编写自己的,使用现有的库。通常 Web 服务器框架会透明地执行此操作,您可能必须将其作为中间件插入服务器端代码中的某个位置。

标签: node.js csv post aws-lambda multipartform-data


【解决方案1】:

所以我终于设法解析了从 AWS API Gateway 接收到的数据,并且需要一个正文解析库来获取我需要的 .csv 数据,正如 Tomalak 所说。

这是我最后所做的:

  • 使用 代理集成 设置 AWS API Gateway,它在 lambda 函数中提供 base64 编码格式的 .csv 数据。
  • 使用节点“Buffer”从base64解码数据
  • 为了解析数据,我使用了一个名为“multipart”的库
  • 然后我使用名为“csvtojson”的库将转换后的 FormData 的数据部分(我只有一个文件,因此我在索引 0 处调用该文件)转换为 JSON

从那里我有一个格式很好的 JSON 对象可以使用。我没有意识到您可以直接从标题中提取边界信息,您需要使用“parse-multipart”库来解析数据。

Lambda 代码片段

const multipart = require("parse-multipart");
const csv = require("csvtojson");

exports.handler = async event => {   
    console.log(`Event: ${JSON.stringify(event)}`); 
    const body = Buffer.from(event["body"].toString(), "base64"); // AWS case    
    const boundary = multipart.getBoundary(event.headers["Content-Type"]);
    const buff = multipart.Parse(body, boundary);
    const csvDataString = buff[0].data.toString("utf8");
    const csvData = await csv().fromString(csvDataString);
    console.log(csvData); 
}

【讨论】:

    猜你喜欢
    • 2019-05-30
    • 2018-05-04
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2020-04-26
    • 2018-12-31
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多