部署图书推荐引擎后提交按钮报Method Not Allowed错误求助
搭建了一个包含首页、测验页和推荐页的图书推荐引擎,部署在AWS S3 Bucket上,但测验提交按钮无法正常工作。引擎通过PostgreSQL数据库,根据测验得分映射的genreId查询随机图书推荐,点击提交按钮时出现“Method Not Allowed”错误,尽管已经在server.js中配置了POST请求处理逻辑。以下是相关代码,求排查方向:
quiz.js代码
const { Client } = require('pg'); const dbConfig = { user: 'username', host: 'host', database: 'postgres', password: 'password', port: 5432, ssl: { rejectUnauthorized: false } }; const cors = require('cors'); app.use(cors()); const client = new Client(dbConfig); client.connect() .then(() => { console.log('Connected to the database'); startQuiz(); }) .catch(error => { console.error('Error connecting to the database:', error); }); process.on('exit', () => { client.end(); }); const genreIdMapping = { 7: 3, 8: 3, 9: 6, 10: 6, 11: 8, 12: 8, 13: 7, 14: 4, 15: 1, 16: 9, 17: 9, 18: 10, 19: 10, 20: 2, 21: 5 }; function startQuiz() { console.log('Quiz form loaded'); const quizForm = document.getElementById('quiz-form'); quizForm.addEventListener('submit', (event) => { event.preventDefault(); console.log('Quiz form submitted'); let totalScore = 0; const userScores = {}; for (let i = 1; i <= 7; i++) { const selectedAnswerIndex = parseInt(document.querySelector(`input[name="answer${i}"]:checked`).value); totalScore += questions[i - 1].answers[selectedAnswerIndex].score; userScores[i - 1] = questions[i - 1].answers[selectedAnswerIndex].score; } const genreId = genreIdMapping[totalScore]; if (genreId) { fetch('https://mhtwcqy8pd.execute-api.us-east-2.amazonaws.com/BookWizard', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ genreId }) }) .then(response => response.json()) .then(data => { let resultText = ''; if (data.title) { resultText = ` <h2>Based on your answers, we recommend the following book:</h2> <p>${data.title} by ${data.author}</p> `; } else { resultText = "No book recommendation found for your score."; } const resultContainer = document.getElementById('result-container'); resultContainer.innerHTML = resultText; }) .catch(error => { console.error('Error fetching book recommendation:', error); const resultContainer = document.getElementById('result-container'); resultContainer.innerHTML = "Error fetching book recommendation."; }); } else { console.log("No genre ID mapping found for your score."); const resultContainer = document.getElementById('result-container'); resultContainer.innerHTML = "No genre ID mapping found for your score."; } }); } document.addEventListener('DOMContentLoaded', () => { console.log('Document loaded'); startQuiz(); });
server.js代码
import { Client } from 'pg'; import express from 'express'; import { urlencoded, json } from 'body-parser'; const app = express(); const port = 3000; const cors = require('cors'); app.use(cors()); const dbConfig = { user: 'postgres', host: 'host', database: 'database', password: 'password', port: 5432, ssl: { rejectUnauthorized: false } }; const client = new Client(dbConfig); client.connect() .then(() => { console.log('Connected to the database'); }) .catch(error => { console.error('Error connecting to the database:', error); }); app.use(urlencoded({ extended: false })); app.use(json()); app.use(express.static('public')); app.post('/recommendation', async (req, res) => { try { const { genreId } = req.body; const query = 'SELECT title, author, description, imgurl FROM books WHERE genreId = $1 ORDER BY RANDOM() LIMIT 1'; const { rows } = await client.query(query, [genreId]); if (rows.length > 0) { const recommendation = { title: rows[0].title, author: rows[0].author, description: rows[0].description, imgurl: rows[0].imgurl }; res.json(recommendation); } else { res.json({ message: 'No book recommendation found for this genre' }); } } catch (error) { console.error('Error fetching book recommendation:', error); res.status(500).json({ message: 'Error fetching book recommendation' }); } }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });
请求地址与后端路由不匹配
quiz.js中fetch的目标地址是https://mhtwcqy8pd.execute-api.us-east-2.amazonaws.com/BookWizard,但server.js里的POST接口路由是/recommendation。需确认API Gateway是否将请求转发到了正确的后端路径,或者直接修正fetch地址为完整接口路径,比如https://mhtwcqy8pd.execute-api.us-east-2.amazonaws.com/BookWizard/recommendation。API Gateway方法配置错误
检查AWS API Gateway对应资源是否开启了POST方法,集成请求是否正确指向你的Express服务(比如Lambda/EC2),路径映射是否匹配。如果API Gateway仅允许GET请求,会直接返回Method Not Allowed。前端代码冗余数据库连接
quiz.js是前端浏览器运行代码,却包含了pg数据库连接逻辑——这完全错误,前端不能暴露数据库凭证,也无法在浏览器中直接连接数据库。必须删除这部分代码,前端只负责向后端发送请求,数据库操作全部交给server.js处理。CORS配置遗漏
虽然server.js配置了cors,但通过API Gateway部署时,需要在API Gateway层面也配置CORS规则,允许前端S3域名的POST请求。否则可能出现跨域隐藏错误,间接导致Method Not Allowed。后端服务有效性验证
用Postman或curl直接请求后端POST接口,验证服务是否正常响应。比如执行:curl -X POST -H "Content-Type: application/json" -d '{"genreId":3}' https://mhtwcqy8pd.execute-api.us-east-2.amazonaws.com/BookWizard/recommendation如果该请求也返回Method Not Allowed,说明后端路由或API Gateway配置存在问题。
请求格式验证
确认fetch请求的Content-Type为application/json,且body是有效的JSON字符串。server.js已配置app.use(json())解析请求体,但需确保前端发送的内容格式正确。
内容的提问来源于stack exchange,提问作者April

