我正在写一个基于烧瓶的小型站点,我想使用Ajax将数据从客户端发送到服务器。到目前为止,我仅使用Ajax请求从服务器检索数据。这次我想通过POST请求提交数据。
这是烧瓶侧的接收器,我将其简化为仅记录一条消息,以避免在此路由的实现中出现任何不必要的错误:
@app.route("/json_submit", methods=["POST"]) def submit_handler(): # a = request.get_json(force=True) app.logger.log("json_submit") return {}
提交ajax请求时,flask给了我400错误
127.0.0.1 - - [03/Apr/2014 09:18:50] "POST /json_submit HTTP/1.1" 400 -
我也可以在浏览器的Web开发人员控制台中看到这一点
为什么flask不submit_handler使用请求中提供的数据进行调用?
submit_handler
var request = $.ajax({ url: "/json_submit", type: "POST", data: { id: id, known: is_known }, dataType: "json", }) .done( function (request) { })
如果您使用的是Flask-WTF CSRF保护,则需要免除您的视图或将CSRF令牌也包含在AJAX POST请求中。
豁免是通过装饰器完成的:
@csrf.exempt @app.route("/json_submit", methods=["POST"]) def submit_handler(): # a = request.get_json(force=True) app.logger.log("json_submit") return {}
要将令牌包含在AJAX请求中,请将令牌内插到页面中的某个位置;在<meta>标题或生成的JavaScript中,然后设置X-CSRFToken标题。使用jQuery时,请使用ajaxSetuphook。
<meta>
X-CSRFToken
ajaxSetup
使用元标记的示例(来自Flask-WTF CSRF文档):
<meta name="csrf-token" content="{{ csrf_token() }}">
在您的JS代码中:
var csrftoken = $('meta[name=csrf-token]').attr('content') $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) { xhr.setRequestHeader("X-CSRFToken", csrftoken) } } })
您的处理程序实际上尚未发布JSON数据;它仍然是常规的url编码POST(数据将最终在request.formFlask一侧);您必须将AJAX内容类型设置为application/json并用于JSON.stringify()实际提交JSON:
POST
request.form
application/json
JSON.stringify()
var request = $.ajax({ url: "/json_submit", type: "POST", contentType: "application/json", data: JSON.stringify({ id: id, known: is_known }), }) .done( function (request) { })
现在的数据可以作为一个Python结构与访问request.get_json()方法。
request.get_json()
在dataType: "json",对参数$.ajax时,你的看法是只需要 返回 JSON(例如,你使用flask.json.jsonify()产生JSON响应)。它使jQuery知道如何处理响应。
dataType: "json",
$.ajax
flask.json.jsonify()