JavaScript向Flask传表单数据时request.form获取mac报400错误
问题背景
对接MySQL的网站通过JavaScript渲染动态设备列表表格,表格每行展示单台设备信息并配置操作按钮。点击按钮时需要获取当前行的设备MAC地址,传递到Flask后端执行SQL语句删除该设备的关联数据,目前Flask应用无法正确获取前端传递的MAC地址。
关联代码
前端deleteCustomer方法与通用POST提交方法
function deleteCustomer(obj) { const data = obj.parentNode.parentNode.textContent; macIndex = data.search(":") - 2; mac = data.substr(macIndex, 17) var regex = /^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/; test_flag = regex.test(mac) if (test_flag) { var index = obj.parentNode.parentNode.rowIndex; var table = document.getElementById("deviceTable"); //table.deleteRow(index); console.log("start") parameters = { value: mac, name: "mac" } post("/xgs/unassociate/device", parameters); } } /** * sends a request to the specified url from a form. this will change the window location. * @param {string} path the path to send the post request to * @param {object} params the parameters to add to the url * @param {string} [method=post] the method to use on the form */ function post(path, params, method='post') { const form = document.createElement('form'); form.method = method; form.action = path; for (const key in params) { if (params.hasOwnProperty(key)) { const hiddenField = document.createElement('input'); hiddenField.type = 'hidden'; hiddenField.name = key; hiddenField.value = params[key]; form.appendChild(hiddenField); } } console.log(form); document.body.appendChild(form); form.submit(); }
后端Flask对应路由处理代码
@app.route('/xgs/unassociate/device', methods=['POST']) def unassocCust(): if session.get('logged_in'): user = app_users.get_user() if app_admin.get_permissions()['xgs']: if request.method == 'POST': print("Step 1") mac = request.form["mac"] print("Step 1.5") result = app_xgs.xgs_unassociateCustomer( mac ) data = app_xgs.xgs_devices_with_cust() print("Step 2") return render_template('xgs_unassociate.html', user=user, permissions=app_admin.get_permissions(), data=data) else: return redirect(url_for('page_not_found')) else: return redirect(url_for('login'))
前端动态渲染表格代码
<div id='container'> <script type="text/javascript"> myVar = returnData({{data|tojson}}) document.getElementById('container').innerHTML=createTable(myVar, "unassociate"); </script> </div>
故障现象
浏览器控制台可以看到MAC地址已经正确传入post方法,页面也会正常跳转到/xgs/unassociate/device路由,但Flask后端执行mac = request.form["mac"]时会触发400 Bad Request错误,后端日志仅能打印出"Step 1",无法执行到后续逻辑。
故障原因
前端构造POST提交参数的写法错误:
parameters = { value: mac, name: "mac" }
通用post方法遍历参数对象生成表单项时,会把对象的键作为input的name属性,对象的值作为input的value属性。上述写法最终会生成两个表单项:
- name为
value,值为提取到的MAC地址 - name为
name,值为字符串"mac"
表单提交后根本不存在name="mac"的字段,Flask通过request.form["mac"]获取不存在的键时,会直接返回400错误。
修复方案
修改前端deleteCustomer方法中参数对象的写法,直接将mac作为键,MAC地址作为对应值即可:
parameters = { "mac": mac }
修改后表单提交时会正确生成name="mac"的隐藏字段,后端即可正常获取到MAC地址。
内容的提问来源于stack exchange,提问作者Jash
相关产品推荐
相关产品推荐

