You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在HTML中添加<form>会导致JavaScript与Flask交互功能失效?

表单包裹元素后AJAX更新DOM失效的原因

当把页面中两个输入框和按钮用<form>标签包裹后,原本通过JavaScript的fetch请求获取Flask服务器返回文本、并更新<blockquote>内容的功能就失效了。以下是问题成因分析:

原可正常工作的代码

HTML代码

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="{{ url_for('static', filename='CSSsheets/SBPstyle.css') }}" />
    <title></title>
</head>
<body>
    <input id="expertiseReq" placeholder="leave blank for any skill level" />
    <input id="locationReq" placeholder="leave blank for any location" />
    <button id="gatherNames">Click to Get List of Player Names</button> 
    <blockquote id="playerNamesGoHere" class="properly_sized_blockquote">No Player Names Loaded</blockquote>
    <script src="{{ url_for('static', filename='JSscripts/SBPscript.js') }}"></script>
</body>
</html>

CSS代码

.properly_sized_blockquote {
    border: solid;
    border-block-width: 20px;
    height: 600px;
    width: 150px;
}

JavaScript代码

const gatherPlayersButton = document.getElementById('gatherNames');
const areaForPlayerNames = document.getElementById('playerNamesGoHere')
const summon_players = () => {
    let eR
    let lR
    if (document.getElementById('expertiseReq').value == "") {
        eR = "None";
    } else {
        eR = document.getElementById('expertiseReq').value
    };
    if (document.getElementById('locationReq').value == "") {
        lR = "None";
    } else {
        lR = document.getElementById('locationReq').value
    };
    let tagsString = eR + "," + lR;
    fetch(`/battle?tags=${tagsString}`, { method: "GET" }).then((response) => response.text()).then((text) => {
        areaForPlayerNames.innerText = text;
    });
};

gatherPlayersButton.addEventListener("click", () => summon_players());

Flask服务器代码

from flask import Flask, render_template, request
from static.SNEKfiles import SpaceShipGame
import json


game_app = Flask(__name__)

@game_app.route('/') 
@game_app.route('/home')
def home():
    return render_template("HTMLPage1.html")

@game_app.route('/battle', methods=['GET', 'POST'])
def battle():
    if request.method == 'GET':
        gathering_player_requirements = request.args.get('tags')
        if gathering_player_requirements != None:
            print(gathering_player_requirements)
            skill_requirement = gathering_player_requirements.split(",")[0]
            location_requirement = gathering_player_requirements.split(",")[1]
            gathering_player = SpaceShipGame.Player()
            gathered_player_names = gathering_player.obtainAllPlayerNames(skill_requirement, location_requirement)
            return gathered_player_names
        else:
            return render_template("SingleBattlePage.html")

问题成因分析

核心原因是表单内的按钮默认会触发表单提交行为:

  • 当按钮被包裹在<form>标签内时,如果没有显式指定type="button",浏览器会默认把这个按钮识别为type="submit"(提交按钮)。
  • 点击这个按钮时,浏览器会先执行表单的默认提交逻辑:按照表单的action属性(未指定则提交到当前页面URL)发起请求,同时刷新整个页面。
  • 虽然你的JavaScript代码也绑定了click事件并发起了fetch请求,但页面刷新的速度会比fetch请求的回调执行更快——页面刷新后,原来的DOM元素被重新渲染,fetch回调里更新<blockquote>的操作根本来不及生效,自然看不到服务器返回的文本。

而在没有<form>包裹的情况下,按钮没有默认的提交行为,click事件绑定的fetch请求能正常完成,回调可以顺利更新<blockquote>的内容。

内容的提问来源于stack exchange,提问作者Frasher Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 04:54:34