[英]Flask and Ajax Post HTTP 400 Bad Request Error
I am writing a small flask based site and I would like to send data from the client to the server using Ajax.我正在编写一个基于小烧瓶的站点,我想使用 Ajax 将数据从客户端发送到服务器。 Until now I have only used Ajax requests to retrieve data from the server.
到目前为止,我只使用 Ajax 请求从服务器检索数据。 This time I would like to submit data via POST request.
这次我想通过POST请求提交数据。
This is the receiver on the flask side, I reduced it to barely log a message to avoid any unnecessary errors within the implementation of this route:这是烧瓶端的接收器,我将其简化为几乎不记录消息,以避免在此路由的实现中出现任何不必要的错误:
@app.route("/json_submit", methods=["POST"])
def submit_handler():
# a = request.get_json(force=True)
app.logger.log("json_submit")
return {}
When submitting the ajax request, flask gives me a 400 error提交ajax请求时,flask给我400错误
127.0.0.1 - - [03/Apr/2014 09:18:50] "POST /json_submit HTTP/1.1" 400 -
I can also see this in the web developer console in the browser我也可以在浏览器的 Web 开发者控制台中看到这一点
Why is flask not calling submit_handler
with the supplied data in the request?为什么flask没有使用请求中提供的数据调用
submit_handler
?
var request = $.ajax({
url: "/json_submit",
type: "POST",
data: {
id: id,
known: is_known
},
dataType: "json",
})
.done( function (request) {
})
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.如果您使用Flask-WTF CSRF 保护,则需要在 AJAX POST 请求中免除您的视图或包含 CSRF 令牌。
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 {}
To include the token with AJAX requests, interpolate the token into the page somewhere;要将令牌包含在 AJAX 请求中,请将令牌插入页面的某个位置; in a
<meta>
header or in generated JavaScript, then set a X-CSRFToken
header.在
<meta>
标头或生成的 JavaScript 中,然后设置X-CSRFToken
标头。 When using jQuery, use the ajaxSetup
hook .使用 jQuery 时,请使用
ajaxSetup
hook 。
Example using a meta tag (from the Flask-WTF CSRF documentation):使用元标记的示例(来自 Flask-WTF CSRF 文档):
<meta name="csrf-token" content="{{ csrf_token() }}">
and in your JS code somewhere:并在您的 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)
}
}
})
Your handler doesn't actually post JSON data yet;您的处理程序实际上还没有发布 JSON 数据; it is still a regular url-encoded
POST
(the data will end up in request.form
on the Flask side);它仍然是一个常规的 url 编码的
POST
(数据将在 Flask 端的request.form
结束); you'd have to set the AJAX content type to application/json
and use JSON.stringify()
to actually submit JSON:您必须将 AJAX 内容类型设置为
application/json
并使用JSON.stringify()
来实际提交 JSON:
var request = $.ajax({
url: "/json_submit",
type: "POST",
contentType: "application/json",
data: JSON.stringify({
id: id,
known: is_known
}),
})
.done( function (request) {
})
and now the data can be accessed as a Python structure with the request.get_json()
method .现在可以使用
request.get_json()
方法将数据作为 Python 结构访问。
The dataType: "json",
parameter to $.ajax
is only needed when your view returns JSON (eg you usedflask.json.jsonify()
to produce a JSON response). dataType: "json",
$.ajax
参数仅在您的视图返回JSON 时才需要(例如,您使用flask.json.jsonify()
生成 JSON 响应)。 It lets jQuery know how to process the response.它让 jQuery 知道如何处理响应。
Can you try like this你可以这样试试吗
var request = $.ajax({
url: "/json_submit",
type: "POST",
contentType: "application/json",
data: JSON.stringify({
id: id,
known: is_known
}),
dataType: "json",
})
.done( function (request) {
})
Before that, In your code returns dict object.在此之前,在您的代码中返回 dict 对象。 That is not correct.
那是不正确的。 It returns json like
它返回 json 就像
@app.route("/json_submit", methods=["POST"])
def submit_handler():
# a = request.get_json(force=True)
app.logger.log("json_submit")
return flask.jsonify({'msg': 'success'})
A similar solution that does not require jQuery不需要jQuery的类似解决方案
<meta name="csrf-token" content="{{ csrf_token() }}">
var beforeSend = function(xhr) {
var csrf_token = document.querySelector('meta[name=csrf-token]').content;
xhr.setRequestHeader("X-CSRFToken", csrf_token);
};
function fooFunction() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/json-submit");
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Do what you want with this.responseText
}
};
beforeSend(xhr);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify({
'id': id, 'known': is_known
}));
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.