Flask应用fetch请求无法获取JSON数据,如何实现掷骰子功能?
解决Flask路由返回HTML而非JSON导致fetch报错的问题
问题根源
你的/character路由当前返回的是HTML模板,但前端fetch()请求期望获取JSON格式数据,因此拿到HTML内容后尝试解析JSON时触发语法错误。
解决方案一:新增独立API路由处理掷骰子请求
将页面渲染和API数据请求拆分为两个独立路由,避免冲突:
后端代码
from flask import Flask, render_template, jsonify import random app = Flask(__name__) # 负责返回页面的路由 @app.route('/character') def character_page(): return render_template('character.html') # 你的HTML模板文件 # 专门返回掷骰子JSON结果的API路由 @app.route('/api/roll-dice') def roll_dice(): # 生成6面骰子投掷结果,示例为5次投掷 throws = [random.randint(1, 6) for _ in range(5)] return jsonify(throws)
前端代码
// 绑定按钮点击事件 document.querySelector('#roll-btn').addEventListener('click', async () => { try { const response = await fetch('/api/roll-dice'); if (!response.ok) throw new Error('请求失败'); const diceResult = await response.json(); console.log('掷骰子结果:', diceResult); // 这里可将结果渲染到页面指定位置 } catch (err) { console.error('出错了:', err); } });
解决方案二:在同一路由中根据请求类型返回不同内容
如果不想新增路由,可通过判断请求头,决定返回HTML还是JSON:
后端代码
from flask import Flask, render_template, jsonify, request import random app = Flask(__name__) @app.route('/character') def character(): # 判断请求是否期望JSON格式 if request.accept_mimetypes.accept_json and not request.accept_mimetypes.accept_html: throws = [random.randint(1, 6) for _ in range(5)] return jsonify(throws) # 默认返回HTML模板 return render_template('character.html')
前端代码
document.querySelector('#roll-btn').addEventListener('click', async () => { try { const response = await fetch('/character', { headers: { 'Accept': 'application/json' // 明确告诉后端需要JSON } }); if (!response.ok) throw new Error('请求失败'); const diceResult = await response.json(); console.log('掷骰子结果:', diceResult); } catch (err) { console.error('出错了:', err); } });
关键注意事项
- 优先使用Flask自带的
jsonify()方法返回JSON,它会自动设置正确的Content-Type: application/json响应头,比手动用make_response(json.dumps(throws))更可靠(手动方式需自行设置响应头,否则前端可能无法识别数据格式)。 - 前端
fetch()需先通过response.ok判断请求是否成功,再解析JSON,避免后端返回错误状态码时仍尝试解析导致报错。
内容的提问来源于stack exchange,提问作者Rafał Tomaszewski
相关产品推荐
相关产品推荐

