使用AJAX向DynamoDB发起POST请求时遇400错误求助
兄弟,我之前也踩过一模一样的坑!Lambda在AWS控制台测试完全正常,一到前端表单提交就报400,这基本不是Lambda本身的问题,大概率是API Gateway的配置或者前端请求格式没匹配上。给你梳理几个最关键的排查方向:
先查API Gateway的请求集成配置
首先确认你的API Gateway是不是把POST请求正确映射到了Lambda函数,尤其是Content-Type的匹配:如果前端表单默认发送application/x-www-form-urlencoded格式的数据,但你在API Gateway的集成请求里只配置了application/json的映射模板,肯定会直接报400。
解决办法:去API Gateway的「集成请求」里,添加application/x-www-form-urlencoded的映射模板,把表单数据转成Lambda能处理的JSON格式,模板内容可以写:{ "body": $input.json('$') }另外!改完配置一定要重新部署API到production阶段,不然前端访问的还是旧配置,白忙活一场。
检查前端表单的提交格式
纯HTML表单默认会以application/x-www-form-urlencoded格式发送数据,如果你的Lambda期望接收JSON格式,自然会解析失败导致400。两种解决思路:- 用JavaScript手动构造JSON请求发送,比如给表单加个提交事件监听:
document.querySelector('form').addEventListener('submit', async (e) => { e.preventDefault(); // 阻止默认表单提交 const formData = new FormData(e.target); const payload = Object.fromEntries(formData); try { const response = await fetch('https://quovje1gi8.execute-api.us-east-2.amazonaws.com/production/accounts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); console.log('提交成功:', result); } catch (err) { console.error('提交失败:', err); } }); - 保持表单默认提交方式,但确保API Gateway能正确解析表单编码的数据(就是前面说的添加映射模板)。
- 用JavaScript手动构造JSON请求发送,比如给表单加个提交事件监听:
别忽略CORS和请求验证
虽然你说权限没问题,但还是确认下API Gateway的CORS配置:如果前端和API Gateway不在同一个域名,必须在API Gateway的「CORS设置」里允许你的前端域名发起POST请求,Allowed Methods要包含POST,Allowed Origins设成你的前端域名或者*(测试用)。有时候浏览器会把跨域错误伪装成400,这点很容易被忽略。
另外,检查API Gateway有没有开启请求验证,如果设置了必填参数但前端没传,也会直接返回400。可以暂时关闭验证测试一下,或者调整验证规则。去CloudWatch看日志找具体原因
前端的400太笼统了,直接去AWS CloudWatch看API Gateway和Lambda的日志!API Gateway的日志会告诉你是请求格式不对、验证失败还是集成出错,Lambda的日志能看到有没有收到请求、参数是不是正确。
开启方法:在API Gateway的阶段设置里打开日志记录,然后去CloudWatch的Log Groups里找对应的日志组,里面的详细错误信息能帮你快速定位问题,比如"Invalid request body"或者"Missing required parameter"。
先从这几点排查,尤其是请求格式和API Gateway的映射模板,大概率能解决问题。
内容的提问来源于stack exchange,提问作者Adam Donabed

