AWS Lambda SQS轮询器发HTTP请求后SQS消息体无法存入数据库求助
问题根因与修复方案
核心问题根因
- Lambda侧
async处理器未等待HTTP请求完成就提前结束执行:Node.js原生http.request是回调式异步API,你没有将其包装为Promise等待执行完成,Lambda会在req.end()执行后立即冻结运行环境,大概率POST请求未完整发送,导致PHP侧接收到的JSON payload不完整/为空,json_decode执行失败返回null,最终取到的body值为空。 - 潜在协议适配问题:如果你的目标接口
mylink.com是HTTPS协议,使用http模块发起请求会直接失败,也会导致payload传输异常。 - PHP侧代码存在缺陷:直接拼接SQL语句,既存在SQL注入风险,当SQS的body内容包含单引号时会触发SQL语法错误,也会导致插入内容为空。
修复步骤
1. 调整Lambda侧代码
将HTTP请求包装为Promise,在async handler中等待请求执行完成,同时根据目标接口协议选择http/https模块:
// 如果目标接口是HTTPS,替换为 require('https') const http = require('http'); exports.handler = async (event) => { const postData = JSON.stringify(event); const options = { 'method': 'POST', 'hostname': 'mylink.com', 'path': '/index.php?route=report', 'headers': { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } }; // 包装为Promise等待请求完成 return new Promise((resolve, reject) => { const req = http.request(options, function (res) { const chunks = []; res.on("data", function (chunk) { chunks.push(chunk); }); res.on("end", function () { const body = Buffer.concat(chunks).toString(); console.log('接口返回:', body); resolve(body); }); res.on("error", function (error) { console.error('请求错误:', error); reject(error); }); }); req.on('error', (e) => { console.error(`请求遇到问题: ${e.message}`); reject(e); }); req.write(postData); req.end(); console.log('发送的payload:', postData); }); };
2. 调整PHP侧代码
增加JSON解析校验,使用预处理语句避免SQL注入和语法错误:
public function report(){ $dataJson = file_get_contents('php://input'); $decode = json_decode($dataJson, true); // 校验JSON解析结果和字段存在性,可选新增日志打印方便后续排查 if (json_last_error() !== JSON_ERROR_NONE || !isset($decode['Records'][0]['body'])) { exit('参数错误'); } $body = $decode['Records'][0]['body']; // 使用预处理语句插入数据 $stmt = $this->db->prepare("INSERT INTO report_data (report_id, text, date_added) VALUES (NULL, ?, current_timestamp())"); $stmt->bind_param('s', $body); $stmt->execute(); $stmt->close(); }
内容的提问来源于stack exchange,提问作者ferdinand
相关产品推荐
相关产品推荐

