且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Flask和Ajax发布HTTP 400错误的请求错误

更新时间:2022-01-31 07:26:42

如果您使用的是 Flask-WTF CSRF保护,您将需要免除视图或将CSRF令牌也包含在AJAX POST请求中.

If you are using the Flask-WTF CSRF protection you'll need to either exempt your view or include the CSRF token in your AJAX POST request too.

免除是通过装饰器完成的:

Exempting is done with a decorator:

@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时,请使用 ajaxSetup 钩子.

To include the token with AJAX requests, interpolate the token into the page somewhere; in a <meta> header or in generated JavaScript, then set a X-CSRFToken header. When using jQuery, use the ajaxSetup hook.

使用元标记的示例(来自Flask-WTF CSRF文档):

Example using a meta tag (from the Flask-WTF CSRF documentation):

<meta name="csrf-token" content="{{ csrf_token() }}">

以及您的JS代码中的某个地方:

and in your JS code somewhere:

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 (数据最终会在Flask的 request.form 中结束);您必须将AJAX内容类型设置为 application/json 并使用 JSON.stringify()实际提交JSON:

Your handler doesn't actually post JSON data yet; it is still a regular url-encoded POST (the data will end up in request.form on the Flask side); you'd have to set the AJAX content type to application/json and use JSON.stringify() to actually submit JSON:

var request = $.ajax({
   url: "/json_submit",
   type: "POST",
   contentType: "application/json",
   data: JSON.stringify({
     id: id, 
     known: is_known
   }),  
})  
  .done( function (request) {
})

,现在可以使用 request作为Python结构访问数据.get_json()方法.

and now the data can be accessed as a Python structure with the request.get_json() method.

仅当视图返回 JSON(例如,使用href ="https://flask.readthedocs.org/en/latest/api/#flask.json.jsonify"> flask.json.jsonify() 以产生JSON响应).它使jQuery知道如何处理响应.

The dataType: "json", parameter to $.ajax is only needed when your view returns JSON (e.g. you used flask.json.jsonify() to produce a JSON response). It lets jQuery know how to process the response.