我希望能够将数据发送到我的 Flask 应用程序。我试过访问 request.data
但它是一个空字符串。您如何访问请求数据?
from flask import request
@app.route('/', methods=['GET', 'POST'])
def parse_request():
data = request.data # data is empty
# need posted data here
这个问题的答案让我接下来问Get raw POST body in Python Flask regardless of Content-Type header,这是关于获取原始数据而不是解析数据的问题。
docs 描述了请求期间 request
对象 (from flask import request
) 上可用的属性。在最常见的情况下,request.data
将是空的,因为它被用作后备:
request.data 以字符串形式包含传入的请求数据,以防它带有 Flask 无法处理的 mimetype。
request.args:URL 查询字符串中的键/值对
request.form:正文中的键/值对,来自 HTML 表单或非 JSON 编码的 JavaScript 请求
request.files:正文中的文件,Flask 与表单分开。 HTML 表单必须使用 enctype=multipart/form-data 否则将不会上传文件。
request.values:组合 args 和 form,如果键重叠,则首选 args
request.json:解析后的 JSON 数据。请求必须具有 application/json 内容类型,或使用 request.get_json(force=True) 忽略内容类型。
所有这些都是 MultiDict
实例(json
除外)。您可以使用以下方式访问值:
request.form['name']:如果您知道密钥存在,则使用索引
request.form.get('name'):如果密钥可能不存在,则使用 get
request.form.getlist('name'):如果密钥被多次发送并且您想要一个值列表,则使用 getlist。 get 只返回第一个值。
要获取原始数据,请使用 request.data
。这仅在无法解析为表单数据时才有效,否则它将为空并且 request.form
将具有解析的数据。
from flask import request
request.data
对于 URL 查询参数,请使用 request.args
。
search = request.args.get("search")
page = request.args.get("page")
对于已发布的表单输入,请使用 request.form
。
email = request.form.get('email')
password = request.form.get('password')
对于使用内容类型 application/json
发布的 JSON,请使用 request.get_json()
。
data = request.get_json()
这是解析发布的 JSON 数据并将其回显的示例。
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/foo', methods=['POST'])
def foo():
data = request.json
return jsonify(data)
使用 curl 发布 JSON:
curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo
或者使用邮递员:
https://i.stack.imgur.com/2CaoI.png
无论内容类型如何,要获取原始帖子正文,请使用 request.get_data()
。如果您使用 request.data
,它会调用 request.get_data(parse_form_data=True)
,这将填充 request.form
MultiDict
并将 data
留空。
如果您发布内容类型为 application/json
的 JSON,请使用 request.get_json()
在 Flask 中获取它。如果内容类型不正确,则返回 None
。如果数据不是 JSON,则会引发错误。
@app.route("/something", methods=["POST"])
def do_something():
data = request.get_json()
要将 request.form
作为普通字典,请使用 request.form.to_dict(flat=False)
。
要返回 API 的 JSON 数据,请将其传递给 jsonify
。
此示例将表单数据作为 JSON 数据返回。
@app.route('/form_to_json', methods=['POST'])
def form_to_json():
data = request.form.to_dict(flat=False)
return jsonify(data)
这是一个使用 curl 的 POST 表单数据示例,以 JSON 形式返回:
$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
"name": "ivanleoncz",
"role": "Software Developer"
}
使用 request.get_json()
获取发布的 JSON 数据。
data = request.get_json()
name = data.get('name', '')
使用 POST 方法提交表单时,使用 request.form
获取数据。
name = request.form.get('name', '')
使用 request.args
获取在 URL 的查询字符串中传递的数据,例如使用 GET 方法提交表单时。
request.args.get("name", "")
request.form
等类似 dict,如果未通过,则使用 get
方法获取具有默认值的值。
要获取没有 application/json
内容类型的 JSON,请使用 request.get_json(force=True)
。
@app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
language = req_data['language']
return 'The language value is: {}'.format(language)
要在 JavaScript 中使用 jQuery 发布 JSON,请使用 JSON.stringify
转储数据,并将内容类型设置为 application/json
。
var value_data = [1, 2, 3, 4];
$.ajax({
type: 'POST',
url: '/process',
data: JSON.stringify(value_data),
contentType: 'application/json',
success: function (response_data) {
alert("success");
}
});
使用 request.get_json()
在 Flask 中解析它。
data = request.get_json()
导入请求:
from flask import request
网址查询参数:
name = request.args.get("name")
age = request.args.get("age")
表单输入:
name = request.form.get('name')
age = request.form.get('age')
或(如果您知道键存在,则使用索引,指定输入字段的名称)
name = request.form['name']
age = request.form['age']
JSON 数据(对于内容类型 application/json)
data = request.get_json()
原始数据作为 request.stream
从 WSGI 服务器传递到 Flask 应用程序。流的长度在 Content-Length
标头中。
length = request.headers["Content-Length"]
data = request.stream.read(length)
改用 request.get_data()
通常更安全。
这是发布表单数据以将用户添加到数据库的示例。检查 request.method == "POST"
以检查表单是否已提交。使用 request.form
中的键来获取表单数据。否则使用 <form>
呈现 HTML 模板。表单中的字段应具有与 request.form
中的键匹配的 name
属性。
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route("/user/add", methods=["GET", "POST"])
def add_user():
if request.method == "POST":
user = User(
username=request.form["username"],
email=request.form["email"],
)
db.session.add(user)
db.session.commit()
return redirect(url_for("index"))
return render_template("add_user.html")
<form method="post">
<label for="username">Username</label>
<input type="text" name="username" id="username">
<label for="email">Email</label>
<input type="email" name="email" id="email">
<input type="submit">
</form>
您可以从
request.form 用于表单数据,这包括表单和文件数据,request.json 和 request.get_json 用于 JSON 数据 request.headers 用于标头 request.args 用于获取查询参数
它们都像字典,如果您知道密钥存在,则使用 request.form['name']
,如果它是可选的,则使用 request.form.get('name')
。
要解析 JSON,请使用 request.get_json()
。
@app.route("/something", methods=["POST"])
def do_something():
result = handle(request.get_json())
return jsonify(data=result)
在编写一个应该发送 JSON 数据的 Slack 机器人时,我得到了一个有效载荷,其中 Content-Type
是 application/x-www-form-urlencoded
。
我尝试了 request.get_json()
,但它不起作用。
@app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
相反,我使用 request.form
来获取 包含 JSON 的表单数据字段,然后加载它。
from flask import json
@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():
req_data = json.loads(request.form["payload"])
如果内容类型被识别为表单数据,request.data
会将其解析为 request.form
并返回一个空字符串。
要获取原始数据而不考虑内容类型,请调用 request.get_data()
。 request.data
调用 get_data(parse_form_data=True)
,如果您直接调用,则默认为 False
。
如果正文被识别为表单数据,它将在 request.form
中。如果是 JSON,它将在 request.get_json()
中。否则原始数据将在 request.data
中。如果您不确定如何提交数据,可以使用 or
链获取第一个包含数据的链。
def get_request_data():
return (
request.args
or request.form
or request.get_json(force=True, silent=True)
or request.data
)
request.args
包含从查询字符串中解析的 args,无论正文中包含什么内容,因此如果它和正文应同时数据,您将从 get_request_data()
中删除它。
使用 HTML 表单发布表单数据时,请确保 input
标记具有 name
属性,否则它们不会出现在 request.form
中。
@app.route('/', methods=['GET', 'POST'])
def index():
print(request.form)
return """
<form method="post">
<input type="text">
<input type="text" id="txt2">
<input type="text" name="txt3" id="txt3">
<input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])
只有 txt3
输入有 name
,所以它是 request.form
中唯一的键。
@app.route('/addData', methods=['POST'])
def add_data():
data_in = mongo.db.Data
id = request.values.get("id")
name = request.values.get("name")
newuser = {'id' : id, 'name' : name}
if voter.find({'id' : id, 'name' : name}).count() > 0:
return "Data Exists"
else:
data_in.insert(newuser)
return "Data Added"
我只是面临同样的需求。我必须保存信息以防出现任何意外情况。所以,我使用以下公式:
Info = "%s/%s/%s" % (request.remote_addr, repr(request), repr(session))
repr(request) 将给出基本信息的字符串表示。您可以使用以下命令添加用户代理数据: request.headers.get('User-Agent')
我还保存了会话大陆,因为它可能包含有价值的信息
试试——>
from flask import request
@app.route('/', methods=['GET', 'POST'])
def parse_request():
if request.method == 'POST':
data = request.form.get('data')
request.data
这很好用,但请记住它是以字符串形式出现的,需要迭代。