AWS Lambda中Axios GET请求失效及404问题排查求助
AWS Lambda + Express 聊天机器人故障排查与修复
问题1:调用服务返回404(Cannot GET /)
原因
- 代码仅定义了
POST /chat路由,但实际调用的是根路径GET /,Express找不到对应路由返回404 - API Gateway与Lambda的路径映射可能未正确配置,导致请求未转发到
/chat端点
修复步骤
- 修正请求端点:确保客户端发送
POST请求到/chat路径,而非GET / - 检查API Gateway配置:
- 确认API Gateway的资源路径设置为
/chat - 绑定的HTTP方法为
POST,并正确关联到Lambda函数
- 确认API Gateway的资源路径设置为
- 可选:添加根路径测试路由(方便验证服务可用性):
app.get('/', (req, res) => { res.status(200).json({ message: '服务正常,请使用POST /chat端点' }); });
问题2:Axios无法获取外部网站内容
可能原因
- Lambda执行角色缺少出站网络权限(如VPC配置限制、安全组未开放出站规则)
- 目标URL不可访问或返回错误
- 异步初始化逻辑存在时序问题:
fs.readFile是异步操作,可能在路由处理时网站内容还未加载完成
修复步骤
- 检查Lambda网络权限:
- 如果Lambda部署在VPC私有子网,需配置NAT网关允许出站HTTP请求
- 确保安全组允许出站到目标域名的443端口
- 验证目标URL可用性:
- 在本地运行代码测试
axios.get请求是否能正常返回数据 - 查看Lambda日志(CloudWatch)中的具体错误信息,定位请求失败原因
- 在本地运行代码测试
- 调整初始化逻辑时序:
将异步文件读取和网站内容加载改为同步或确保在服务启动前完成,示例修改:// 替换原有的fs.readFile异步逻辑 try { const mike_prompt = fs.readFileSync(__dirname + '/mike_prompt.txt', 'utf8'); conversations['user'].push({ role: 'system', content: mike_prompt }); await initializeWebsiteContent(); } catch (err) { console.error('加载prompt文件失败:', err); } // 用IIFE确保初始化在服务就绪前完成 (async () => { try { const mike_prompt = fs.readFileSync(__dirname + '/mike_prompt.txt', 'utf8'); conversations['user'].push({ role: 'system', content: mike_prompt }); await initializeWebsiteContent(); console.log('初始化完成'); } catch (err) { console.error('初始化失败:', err); } })();
补充代码优化点
- 路由中
conversations[sender]可能未初始化,需添加判断:if (!conversations[sender]) { // 复制默认system消息到新用户会话 conversations[sender] = [...conversations['user']]; }
用户原始代码与返回结果
原始代码
// Import the required libraries const express = require('express'); const bodyParser = require('body-parser'); const OpenAI = require('openai'); const cors = require('cors'); const fs = require('fs'); const dotenv = require('dotenv'); const serverless = require('serverless-http'); const axios = require('axios'); dotenv.config(); // Initialize the Express application const app = express(); app.use(cors()); // Use body-parser to parse JSON request bodies app.use(bodyParser.json()); // Initialize the OpenAI client const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, }); // In-memory store for conversations const conversations = {}; conversations['user'] = []; // Fetch content from michaelani.com and its subpages const initializeWebsiteContent = async () => { try { const homeContent = await axios.get('https://r.jina.ai/https://michaelani.com/'); const bioContent = await axios.get('https://r.jina.ai/https://michaelani.com/Autobiography'); const hobbContent = await axios.get('https://r.jina.ai/https://michaelani.com/Hobbies'); conversations['user'].push({ role: 'system', content: homeContent.data }); conversations['user'].push({ role: 'system', content: bioContent.data }); conversations['user'].push({ role: 'system', content: hobbContent.data }); } catch (error) { console.error(`Error initializing website content: ${error.message}`); } }; fs.readFile(__dirname + '/mike_prompt.txt', async (err, data) => { if (err) throw err; const mike_prompt = data.toString(); conversations['user'].push({ role: 'system', content: mike_prompt }); await initializeWebsiteContent(); }); // Define a POST route for the chatbot app.post('/chat', async (req, res) => { const { sender, message } = req.body; // Extract the message from the request body if (!sender || !message) { return res.status(400).json({ error: 'User ID and message are required' }); } conversations[sender].push({ role: 'user', content: message }); try { // Send the message to OpenAI and get the response const response = await client.chat.completions.create({ messages: conversations[sender], model: "gpt-4o", }); const responseString = response.choices[0].message.content; conversations[sender].push({ role: 'assistant', content: responseString }); console.log(responseString); // Send the chatbot's reply back to the client res.json({ reply: responseString }); } catch (error) { // Handle any errors that occur res.status(500).json({ error: error.message }); } }); // Export the app for Lambda module.exports.handler = serverless(app);
返回结果
{ "statusCode": 404, "headers": { "x-powered-by": "Express", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "x-content-type-options": "nosniff", "content-type": "text/html; charset=utf-8", "content-length": "139" }, "isBase64Encoded": false, "body": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /</pre>\n</body>\n</html>\n" }
内容的提问来源于stack exchange,提问作者Michael Ani
相关产品推荐
相关产品推荐

