Flask+Fetch点击按钮加载空白页而非更新当前页面问题求助
解决Flask宝可梦游戏页面跳转与响应显示问题
核心问题分析
- 点击按钮后页面跳转:表单默认提交行为未被阻止,浏览器直接发送请求并刷新页面
- 显示
[object Response]:未正确解析fetch返回的Response对象,直接将其插入DOM
分步解决方案
1. 阻止表单默认提交行为并正确处理响应
修改battle.js,拦截默认提交行为,解析JSON响应后更新页面:
const form = document.getElementById('pokemon-select-form'); form.addEventListener('submit', async (e) => { e.preventDefault(); // 阻止页面跳转的关键 // 获取选中的宝可梦名称(假设按钮带data-pokemon属性) const selectedBtn = e.submitter; const userPokemonName = selectedBtn.dataset.pokemon; try { const response = await fetch('/select-pokemon', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ pokemon_name: userPokemonName }) }); if (!response.ok) throw new Error('请求失败'); const pokemonData = await response.json(); // 解析JSON格式的响应 // 更新宝可梦属性展示 const statsArea = document.getElementById('pokemon-stats'); statsArea.innerHTML = ` <h3>${pokemonData.name}</h3> <p>HP: ${pokemonData.hp}</p> <p>攻击: ${pokemonData.attack}</p> <p>防御: ${pokemonData.defense}</p> `; // 添加新按钮与游戏消息 const actionArea = document.getElementById('game-actions'); actionArea.innerHTML = '<button id="start-battle">开始对战</button>'; const messageArea = document.getElementById('game-message'); messageArea.textContent = `你选择了${pokemonData.name},准备好战斗了吗?`; } catch (err) { console.error(err); document.getElementById('game-message').textContent = '选择宝可梦失败,请重试'; } });
2. Flask后端返回标准JSON响应
修改app.py的路由,确保返回JSON格式数据而非纯文本:
from flask import Flask, render_template, request, jsonify app = Flask(__name__) # 模拟宝可梦数据 POKEMON_DB = { '皮卡丘': {'hp': 35, 'attack': 55, 'defense': 40}, '妙蛙种子': {'hp': 45, 'attack': 49, 'defense': 49}, '杰尼龟': {'hp': 44, 'attack': 48, 'defense': 65} } @app.route('/battle') def battle_page(): return render_template('battle.html') @app.route('/select-pokemon', methods=['POST']) def select_pokemon(): req_data = request.get_json() pokemon_name = req_data.get('pokemon_name') stats = POKEMON_DB.get(pokemon_name) if not stats: return jsonify({'error': '该宝可梦不存在'}), 404 return jsonify({ 'name': pokemon_name, 'hp': stats['hp'], 'attack': stats['attack'], 'defense': stats['defense'] }) if __name__ == '__main__': app.run(debug=True)
3. 调整HTML结构,预留更新区域
修改battle.html,添加用于展示内容的容器:
<!DOCTYPE html> <html> <head> <title>宝可梦文本对战</title> </head> <body> <h1>选择你的初始宝可梦</h1> <form id="pokemon-select-form"> <button type="submit" data-pokemon="皮卡丘">皮卡丘</button> <button type="submit" data-pokemon="妙蛙种子">妙蛙种子</button> <button type="submit" data-pokemon="杰尼龟">杰尼龟</button> </form> <!-- 预留动态更新区域 --> <div id="pokemon-stats"></div> <div id="game-message"></div> <div id="game-actions"></div> <script src="{{ url_for('static', filename='battle.js') }}"></script> </body> </html>
关键注意事项
- 确保
battle.js放在Flask项目的static目录下,否则无法加载 - 按钮需设置
type="submit"并绑定到表单,统一由事件监听器处理 - 使用
async/await处理异步请求,避免回调嵌套 - Flask的
jsonify会自动设置正确的响应头,无需手动添加
内容的提问来源于stack exchange,提问作者NucyLoodle
相关产品推荐
相关产品推荐

