我正在编写一个基于小瓶子的站点,我想使用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开发者控制台中看到这个
为什么烧瓶没有使用请求中提供的数据调用submit_handler
?
var request = $.ajax({
url: "/json_submit",
type: "POST",
data: {
id: id,
known: is_known
},
dataType: "json",
})
.done( function (request) {
})
答案 0 :(得分:26)
如果您使用的是Flask-WTF CSRF protection,则您需要在您的AJAX POST请求中免除您的观看或包含CSRF令牌。
豁免是由装饰者完成的:
@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
hook。
使用元标记的示例(来自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数据;它仍然是一个常规的网址编码POST
(数据最终将在Flask一侧的request.form
中);您必须将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) {
})
现在可以使用request.get_json()
method作为Python结构访问数据。
只有在您的视图返回 JSON时才需要dataType: "json",
$.ajax
参数{例如,您使用flask.json.jsonify()
生成JSON响应)。它让jQuery知道如何处理响应。
答案 1 :(得分:1)
你能尝试这样吗
var request = $.ajax({
url: "/json_submit",
type: "POST",
contentType: "application/json",
data: JSON.stringify({
id: id,
known: is_known
}),
dataType: "json",
})
.done( function (request) {
})
在此之前,在您的代码中返回dict对象。这是不正确的。它返回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'})
答案 2 :(得分:0)
不需要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
}));
};