
flask 接收 xmlhttprequest 的 post 请求时返回 400 错误,通常是因为前端未按 `application/x-www-form-urlencoded` 格式提交数据,而 flask 的 `request.form` 仅解析该格式;本文详解如何用 `formdata` 正确提交 json 字符串并避免 400 错误。
在 Flask 中,request.form 仅能解析符合 application/x-www-form-urlencoded(即表单编码)或 multipart/form-data 格式的请求体。而原始 JavaScript 代码中使用了:
xmlhttpPost.send("json=" + encodeURI(JSON.stringify(newJson)));该写法虽构造了类似查询字符串的文本,但未设置正确的 Content-Type 头(默认为 text/plain),导致 Flask 无法识别并解析为 form 数据,调用 request.form["json"] 时触发 400 Bad Request(因键不存在或解析失败)。
✅ 正确做法是使用 FormData 对象 —— 它会自动设置 Content-Type: multipart/form-data; boundary=...(或在无文件时退化为 application/x-www-form-urlencoded),并确保字段被 Flask 正确捕获。
以下是修复后的完整前端逻辑(含注释与健壮性优化):
function del(e) {
const getReq = new XMLHttpRequest();
getReq.onload = function () {
if (getReq.status !== 200) {
console.error("Failed to fetch JSON:", getReq.statusText);
return;
}
try {
const json = JSON.parse(getReq.responseText);
const newJson = json.filter(item =>
item.name !== e.parentElement?.childNodes[2]?.textContent?.trim()
);
const postReq = new XMLHttpRequest();
postReq.open("POST", "/orders");
postReq.onload = function () {
if (postReq.status === 200) {
location.reload(); // 或更新 UI
} else {
console.error("POST failed:", postReq.statusText);
}
};
const formData = new FormData();
formData.append("json", JSON.stringify(newJson));
postReq.send(formData); // ✅ 自动处理编码与 Content-Type
} catch (err) {
console.error("JSON parsing error:", err);
}
};
getReq.open("GET", "/json");
getReq.send();
}同时,后端 Flask 路由也需增强容错性,避免对空值或缺失字段的直接访问:
from flask import Flask, request, render_template, jsonify
import json
from urllib.parse import unquote
@app.route("/orders", methods=["POST", "GET"])
def order():
global orders
if request.method == "GET":
return render_template("orders.html", orders=orders)
# ✅ 安全获取 form 数据:检查是否存在且非空
if "json" not in request.form or not request.form["json"].strip():
return "", 400 # Bad Request
try:
# ✅ 直接使用 request.form["json"](已确保存在),无需 unquote — FormData 发送时不额外编码
orders = json.loads(request.form["json"])
newOrder(orders) # 假设此函数处理业务逻辑
return "", 200
except json.JSONDecodeError as e:
return f"Invalid JSON: {e}", 400
except Exception as e:
return f"Server error: {e}", 500⚠️ 关键注意事项:
- 不要手动拼接查询字符串 + encodeURI:这无法触发 Flask 的 form 解析器;
- 避免重复使用 xmlhttp 变量名:原代码中内层 const xmlhttp = ... 会遮蔽外层变量,引发作用域错误;
- 始终校验 request.form 键存在性:直接访问 request.form["key"] 在键缺失时抛出 400;
-
优先使用 fetch() 替代 XMLHttpRequest(现代推荐):
fetch("/orders", { method: "POST", body: new FormData().append("json", JSON.stringify(newJson)) });
通过 FormData 提交 + 后端健壮校验,即可彻底解决 Flask 400 错误,确保前后端数据交互稳定可靠。










