You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目中调用AWS Lambda Python函数的问题求助

问题分析与解决方案

你的代码存在几个关键问题,导致无法正确调用Lambda函数,同时S3上传环节也有错误:

1. S3上传参数错误

你直接将本地文件路径filepath传给S3的Body参数,但S3 SDK要求Body必须是文件内容(Buffer/Stream),而非文件路径,这会导致S3上传失败。

2. 异步操作未等待完成

  • s3.upload(params).promise()是异步操作,未使用await会导致S3还未完成上传就调用Lambda,此时S3中不存在目标文件,Lambda自然处理失败。
  • fetch调用Lambda同样是异步操作,未使用await导致无法获取实际返回结果,且extractedText只是一个未resolved的Promise对象。

3. 响应时机错误

直接将未resolved的Promise(results)传给res.send(),不仅不会返回实际的S3上传结果,还会提前结束请求响应,导致后续Lambda调用被中断。

4. 请求方式不匹配

你用method: "post"调用Lambda,但浏览器直接访问URL是GET请求,说明你的API Gateway大概率配置的是GET方法,请求方式不匹配会导致调用失败。


修正后的代码

import fs from 'fs/promises';
import { S3 } from '@aws-sdk/client-s3';
import IncomingForm from 'formidable';

// 禁用Next.js默认的body parser,因为要使用formidable处理表单
export const config = {
  api: {
    bodyParser: false,
  },
};

export default async (req, res) => {
  try {
    // 解析表单数据
    const { fields, files } = await new Promise((resolve, reject) => {
      const form = new IncomingForm();
      form.parse(req, (err, fields, files) => {
        if (err) reject(err);
        else resolve({ fields, files });
      });
    });

    const invoiceFile = files.invoiceFile;
    if (!invoiceFile) {
      return res.status(400).send('未上传文件');
    }

    // 读取本地临时文件内容
    const fileContent = await fs.readFile(invoiceFile.filepath);

    // 初始化S3客户端
    const s3 = new S3({
      accessKeyId: process.env.AWS_ACCESS_KEY,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    });

    // 配置S3上传参数
    const s3Params = {
      Bucket: process.env.AWS_BUCKET_NAME,
      Key: invoiceFile.originalFilename,
      Body: fileContent,
      ContentType: 'application/pdf',
    };

    // 等待S3上传完成
    const s3UploadResult = await s3.upload(s3Params).promise();
    console.log('S3上传完成:', s3UploadResult);

    // 调用Lambda(匹配浏览器访问的GET方法,用encodeURIComponent处理特殊字符)
    const lambdaResponse = await fetch(
      `https://xxxxxx.execute-api.us-east-1.amazonaws.com/?message=${encodeURIComponent(invoiceFile.originalFilename)}`,
      { method: 'GET' }
    );

    if (!lambdaResponse.ok) {
      throw new Error(`Lambda调用失败: ${lambdaResponse.statusText}`);
    }

    // 解析Lambda返回数据(根据实际返回格式调整,比如json/text)
    const extractedText = await lambdaResponse.json();
    console.log('Lambda返回数据:', extractedText);

    // 返回整合结果给前端,方便存入应用状态
    res.status(200).json({
      s3UploadResult,
      extractedText
    });

  } catch (error) {
    console.error('错误详情:', error);
    res.status(500).send(`服务器错误: ${error.message}`);
  }
};

额外注意事项

  • 确认API Gateway与Lambda的集成配置:如果要使用POST方法,需调整API Gateway资源的集成方式,并将参数放在请求体中传递。
  • 增加错误边界处理:比如文件不存在、S3权限不足、Lambda超时等场景的捕获与反馈。
  • 文件名包含特殊字符时,必须用encodeURIComponent转义,避免URL解析错误。

内容的提问来源于stack exchange,提问作者Rich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:01:19