【问题标题】:Get the data received in a Flask request获取 Flask 请求中收到的数据
【发布时间】:2021-09-30 17:57:59
【问题描述】:

我希望能够将数据发送到我的 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,这是关于获取原始数据而不是解析数据。

【问题讨论】:

    标签: python flask werkzeug


    【解决方案1】:

    我只是面临同样的需求。我必须保存信息以防出现任何意外情况。所以,我使用以下公式:

    Info = "%s/%s/%s" % (request.remote_addr, repr(request), repr(session))
    

    repr(request) 将给出基本信息的字符串表示。您可以使用以下命令添加用户代理数据: request.headers.get('User-Agent')

    我还保存会话大陆,因为它可能包含有价值的信息

    【讨论】:

      【解决方案2】:

      你可以从

      获取请求数据
      1. request.form 用于表单数据,包括表单和文件数据,
      2. request.json 和 request.get_json 用于 JSON 数据
      3. request.headers 用于标题
      4. request.args 获取查询参数

      另外,它们都像字典,但它们不是字典,所以最好不要使用request.form['name'],而是使用request.form.get('name')。

      【讨论】:

        【解决方案3】:

        试试->

        from flask import request
        
        @app.route('/', methods=['GET', 'POST'])
        def parse_request():
            if request.method == 'POST':
               data = request.form.get('data')
        

        【讨论】:

          【解决方案4】:

          docs 描述了请求期间request 对象 (from flask import request) 上可用的属性。在最常见的情况下,request.data 将是空的,因为它被用作后备:

          request.data 包含传入的请求数据作为字符串,以防它带有 Flask 无法处理的 mimetype。

          • request.args:URL 查询字符串中的键/值对
          • request.form:正文中的键/值对,来自 HTML 帖子表单或非 JSON 编码的 JavaScript 请求
          • request.files:正文中的文件,Flask 与 form 分开。 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 只返回第一个值。

          【讨论】:

            【解决方案5】:

            导入请求:

            from flask import request
            

            网址查询参数:

            name = request.args.get("name")
            age = request.args.get("age")
            

            表单输入:

            name = request.form.get('name')
            age = request.form.get('age')
            

            OR(如果您知道键存在,则使用索引,指定输入字段的名称)

            name = request.form['name']
            age = request.form['age']
            

            JSON 数据(对于内容类型 application/json)

            data = request.get_json()
            

            【讨论】:

              【解决方案6】:

              在编写一个应该发送 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"])
              

              【讨论】:

                【解决方案7】:
                request.data
                

                这很好用,但请记住它是以字符串形式出现的,需要迭代。

                【讨论】:

                • 已经回答了很多次了,除了迭代字符串没有意义。
                【解决方案8】:
                @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"
                

                【讨论】:

                  【解决方案9】:

                  这是一个发布表单数据以将用户添加到数据库的示例。检查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>
                  

                  【讨论】:

                    【解决方案10】:

                    要将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"
                    }
                    

                    【讨论】:

                      【解决方案11】:

                      要在 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()
                      

                      【讨论】:

                        【解决方案12】:

                        这是一个解析发布的 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
                        

                        或者使用 Postman:

                        【讨论】:

                          【解决方案13】:

                          使用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 方法获取具有默认值的值。

                          【讨论】:

                            【解决方案14】:

                            如果正文被识别为表单数据,它将位于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() 中删除它。

                            【讨论】:

                              【解决方案15】:

                              使用 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 中唯一存在的键。

                              【讨论】:

                                【解决方案16】:

                                如果内容类型被识别为表单数据,request.data 会将其解析为request.form 并返回一个空字符串。

                                要获取无论内容类型如何的原始数据,请致电request.get_data()。 request.data调用get_data(parse_form_data=True),直接调用默认为False。

                                【讨论】:

                                  【解决方案17】:

                                  原始数据从 WSGI 服务器以request.stream 的形式传入 Flask 应用程序。流的长度在Content-Length 标头中。

                                  length = request.headers["Content-Length"]
                                  data = request.stream.read(length)
                                  

                                  改用request.get_data() 通常更安全。

                                  【讨论】:

                                    【解决方案18】:

                                    要解析 JSON,请使用 request.get_json()。

                                    @app.route("/something", methods=["POST"])
                                    def do_something():
                                        result = handle(request.get_json())
                                        return jsonify(data=result)
                                    

                                    【讨论】:

                                      【解决方案19】:

                                      要获取不带 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)
                                      

                                      【讨论】:

                                        【解决方案20】:

                                        无论内容类型如何,要获取原始帖子正文,请使用request.get_data()。如果您使用request.data,它会调用request.get_data(parse_form_data=True),这将填充request.form MultiDict 并将data 留空。

                                        【讨论】:

                                          【解决方案21】:

                                          如果您发布内容类型为 application/json 的 JSON,请使用 request.get_json() 在 Flask 中获取它。如果内容类型不正确,则返回None。如果数据不是 JSON,则会引发错误。

                                          @app.route("/something", methods=["POST"])
                                          def do_something():
                                              data = request.get_json()
                                          

                                          【讨论】:

                                            【解决方案22】:

                                            对于 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()
                                            

                                            【讨论】:

                                              【解决方案23】:

                                              要获取原始数据,请使用request.data。这仅在无法解析为表单数据时才有效,否则它将为空,request.form 将拥有解析后的数据。

                                              from flask import request
                                              request.data
                                              

                                              【讨论】:

                                                猜你喜欢
                                                • 2022-12-10
                                                相关资源
                                                最近更新 更多