Flask中Ajax发送POST请求后端却收到GET请求的问题排查
问题根因
核心问题是你没有拦截表单的原生默认提交行为,另外还有几个隐藏坑会导致功能异常:
- 你给form绑定的
onsubmit="modify_event()"只执行了Ajax逻辑,没有阻止浏览器自带的表单提交动作:你的form标签没有设置action和method属性,浏览器默认会用GET方法把表单参数拼到当前地址(也就是根路径/)后面提交,直接触发页面刷新。这时候Ajax请求要么根本没发出去,要么发送到一半被页面跳转中断,最终后端只能收到携带表单参数的根路径GET请求,和你日志里看到的情况完全一致。 - 之前尝试给提交按钮绑定onclick事件不生效也是同一个原因:点击提交按钮时,会先执行你绑定的onclick逻辑,紧接着还是会触发表单原生提交,只要不拦截这个默认行为,页面必然会跳转。
- Flask-WTF渲染的
{{form1.submit()}}默认生成的是type="submit"的按钮,本身就会触发表单提交,你写的Close按钮设置了type="button"所以不会触发提交,问题就出在这个提交按钮带的默认行为上。 - 额外提醒:你后端现在直接把用户传入的参数拼接SQL语句,存在严重的SQL注入风险,必须修复。
- 小坑预警:你
InfoForm里startdate字段配置的格式是%m-%d-%Y %h:%M,但DateTimeLocalField实际返回的是YYYY-MM-DDTHH:MM格式的字符串,如果后续要用到FlaskForm的校验逻辑,记得把format改成'%Y-%m-%dT%H:%M',不然会校验失败。
修复方案
1. 前端拦截表单默认提交
两种改法选任意一种即可:
改法一:直接在onsubmit绑定里加拦截逻辑
修改form标签的onsubmit属性,加阻止默认行为的代码:
<form id="myForm" onsubmit="event.preventDefault(); modify_event(); return false;">
其中event.preventDefault()是标准的阻止默认事件的写法,return false是兼容老版本浏览器的保险配置,双重保证表单不会触发原生跳转。
改法二:在modify_event函数内部拦截
把函数改成接收事件对象,开头加阻止逻辑:
function modify_event(e) { e.preventDefault(); // 拦截表单原生提交 var value = document.getElementById('startdate').value; $.ajax({ url: "/modify_appointment", type: "POST", data: { new_date : value, id: evId }, success: function () { alert("Modified"); // 可选:提交成功后手动关闭模态框、刷新预约列表 } }); }
对应修改form标签的绑定,把事件对象传进函数:
<form id="myForm" onsubmit="modify_event(event)">
你也可以给form标签显式补上method和action做兜底,就算JS加载失败也不会把请求提交到根路径:
<form id="myForm" onsubmit="event.preventDefault(); modify_event(); return false;" method="POST" action="/modify_appointment">
2. 修复后端SQL注入风险
不要用字符串拼接的方式写SQL,改成参数化查询,由数据库驱动自动做转义:
@app.route("/modify_appointment",methods=["POST"]) def modify_appointment(): cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) getid = request.form['id'] new_date = parser.parse(request.form['new_date']) # 用%s做占位符,参数以元组形式传入,彻底避免SQL注入 cur.execute('UPDATE Appuntamento SET Data = %s WHERE idAppuntamento = %s', (new_date, getid)) mysql.connection.commit() cur.close() msg = 'Modified successfully' return jsonify(msg)
验证方法
改完之后打开浏览器开发者工具的网络面板,点击提交按钮:
- 不会再出现跳转到根路径的GET请求
- 可以看到发往
/modify_appointment的POST请求,请求体里携带new_date和id参数 - 后端正常接收参数更新数据库,前端弹出修改成功的提示
内容的提问来源于stack exchange,提问作者ciacciuli
相关产品推荐
相关产品推荐

