使用JavaScript Fetch向Flask路由提交FormData的JSON响应异常问题
问题:使用Fetch提交Flask投票表单时,返回HTML而非JSON
我实现了一个Flask投票功能,点击按钮提交投票后,路由应该以JSON格式返回更新后的投票数,但通过JavaScript的fetch方法请求时,收到的响应是带有HTML标签的内容,无法解析为JSON,导致报错。
表单代码
<form class="d-inline" id="vote_post" action="/post/22" method="post"> <input id="csrf_token" name="csrf_token" type="hidden" value="IjU4OGEyYTNhMjNmZjhmMTllZjhhYjhlYzgyODFiOTM0NTIzNjZjMWYi.ZtEFxg.XTO0k9Ijne-QNcI2sliKLi4s2KM"> <input id="" name="input_id" type="hidden" value="22"> <button class="btn btn-outline-dark btn-sm border border-dark-subtle px-1 py-0" id="vote_post_btn" type="submit" name="submit" value="vote_post" style="font-size: .65rem;">0</button> </form>
Flask路由代码
@bp.route('/post/<int:id>', methods=['GET', 'POST']) def post(id): post = db.first_or_404(sa.select(Post).where(Post.id == id)) if request.method == 'POST': if request.form.get('submit') == 'vote_post': vote = db.session.execute(sa.select(PostVote).where((PostVote.user_id == current_user.id) & (PostVote.post_id == id))).scalar() count = post.votes_count() if vote is None: vote = PostVote(user_id=current_user.id, post_id=id) count += 1 db.session.add(vote) else: count -= 1 db.session.delete(vote) db.session.commit() return jsonify({"votes": f"{count}"})
JavaScript代码
let post_form = document.getElementById('vote_post'); function sendVote() { let postData = new FormData(post_form); let url = {{ url_for("main.post", id=post.id)|tojson }} fetch(url, { method: "POST", body: postData, }) .then((res) => res.json()) .then((data) => { // this console never prints console.log(data); voteBtn.innerHTML = data["votes"]; }) .catch(console.error); } document.addEventListener('DOMContentLoaded', (event) => { document.getElementById("vote_post").addEventListener("submit", function(e) { e.preventDefault() // Cancel the default action sendVote(); }); });
控制台错误信息
SyntaxError: Unexpected token '<', "<!doctype "... is not valid JSON
Promise.catch
sendVote @ 22:956
(anonymous) @ 22:601
解决方案
问题根源在于:通过Fetch提交的FormData中没有包含投票按钮的submit参数值,导致Flask路由里的request.form.get('submit') == 'vote_post'判断不成立,没有进入返回JSON的逻辑分支,最终返回了页面的HTML内容。
只需在构造FormData后,手动添加按钮的参数即可:
postData.append("submit", document.getElementById("vote_post_btn").value);
内容的提问来源于stack exchange,提问作者user23430396
相关产品推荐
相关产品推荐

