
flask 接收 xmlhttprequest 的 post 数据时返回 400 错误,通常是因为前端未按 `application/x-www-form-urlencoded` 格式提交数据,而 flask 的 `request.form` 仅解析该格式;解决方案是改用 `formdata` 对象封装数据并发送。
在 Flask 中,request.form 是一个类字典对象,专门用于解析标准表单编码(即 Content-Type: application/x-www-form-urlencoded)的请求体。当你直接调用 xmlhttp.send("json=" + encodeURI(...)) 时,虽然字符串结构看似符合表单格式,但 默认情况下 XMLHttpRequest 并未设置正确的 Content-Type 头,导致 Flask 无法识别并解析请求体,进而抛出 400 Bad Request 错误(常见于访问 request.form["json"] 时触发 BadRequestKeyError 或空值校验失败)。
✅ 正确做法是使用 FormData 对象 —— 它会自动设置 Content-Type: multipart/form-data(或在无文件时退化为 application/x-www-form-urlencoded),并确保键值对被 Flask 正确捕获:
function del(e) {
const getXmlhttp = new XMLHttpRequest();
getXmlhttp.onload = function () {
try {
const json = JSON.parse(this.responseText);
const newJson = json.filter(item => item.name !== e.parentElement.childNodes[2].textContent);
const postXmlhttp = new XMLHttpRequest();
postXmlhttp.open("POST", "/orders");
postXmlhttp.onreadystatechange = function () {
if (postXmlhttp.readyState === 4 && postXmlhttp.status === 200) {
// 可选:刷新页面或更新 UI
location.reload();
}
};
const formData = new FormData(); // ✅ 创建 FormData 实例
formData.append("json", JSON.stringify(newJson)); // ✅ 自动编码,无需手动 encodeURI
postXmlhttp.send(formData); // ✅ 自动设置合适 Content-Type
} catch (err) {
console.error("JSON 解析或请求处理失败:", err);
}
};
getXmlhttp.open("GET", "/json");
getXmlhttp.send();
}⚠️ 同时,后端 Flask 路由也需增强健壮性,避免因缺失字段或空值引发异常:
@app.route("/orders", methods=["POST", "GET"])
def order():
global orders
if request.method == "GET":
return render_template("orders.html", orders=orders)
# 安全地获取 form 数据
json_str = request.form.get("json")
if not json_str:
return "Missing 'json' field", 400
try:
orders = json.loads(unquote(json_str))
newOrder(orders) # 假设 newOrder 接收解析后的列表
return "", 204 # No Content 表示成功处理
except json.JSONDecodeError:
return "Invalid JSON in 'json' field", 400
except Exception as e:
return f"Server error: {str(e)}", 500? 关键要点总结:
- ❌ 不要手动拼接查询字符串(如 "json=" + ...)并用 send() 发送纯文本;
- ✅ 必须使用 FormData 封装键值对,让浏览器自动处理编码与头部设置;
- ✅ 后端务必使用 request.form.get(key) 替代 request.form[key],防止 KeyError;
- ✅ 始终校验输入、捕获 JSON 解析异常,并返回明确的 HTTP 状态码便于前端调试。
遵循以上规范,即可彻底解决 Flask + XMLHttpRequest 场景下的 400 错误问题。










