Home > Net >  Flask responds to all POST requests with code 400
Flask responds to all POST requests with code 400

Time:04-28

While working on project based on vue flask I faced a bug related with POST-requests. Flask responds with code 400 to all requests. To reproduce problem:

main.py

import os
from flask import Flask, render_template, request, url_for, redirect
from flask import Flask, render_template, session

app = Flask(__name__)
app.config["SECRET_KEY"] = "fsdijukofhselokiufhdskilujfhsdkihuifs"
@app.route("/test", methods=["POST", "GET"])
def test():
    if request.method == "POST":
        print(request.form["name"])
    return render_template("test.html")

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

test.html(in templates directory)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="text" v-model="name" />
      <button type="submit" variant="danger" v-on:click="submit">Add</button>
      <script lang="Javascript">
        var app = new Vue({
          el: '#app',
          data: {
            name: "",
          },
          methods: {
            submit(event){
              let formData = new FormData();
              formData.append("name", this.name);
              axios({
                url: "/test",
                method: "POST",
                headers: {
                },
                data: formData,
              })
              .then(function (response) {
                console.log(response);
              })
              .catch(function (error) {
                console.log(error);
              });
            }
          },
        })
      </script>
    </div>
  </body>
</html>

After pressing the button I get code 400. 192.168.1.67 - - [27/Apr/2022 17:18:23] "POST /test HTTP/1.1" 400 -

With debug:

File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 2076, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 1518, in full_dispatch_request   
    rv = self.handle_user_exception(e)
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 1516, in full_dispatch_request   
    rv = self.dispatch_request()
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\flask\app.py", line 1502, in dispatch_request        
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "D:\coding\spotinefy1\test.py", line 11, in test
    print(request.form["name"])
  File "C:\Users\andrewtheproger\AppData\Local\Programs\Python\Python310\Lib\site-packages\werkzeug\datastructures.py", line 377, in __getitem__    raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'name' 

Fiddler shows this request: click

In text: ------WebKitFormBoundaryUG2BQoqdARJDgqg4 Content-Disposition: form-data; name "name"

dsadasdasd ------WebKitFormBoundaryUG2BQoqdARJDgqg4--

If try to print request.form, not request.form["name"], I get:

ImmutableMultiDict([('------WebKitFormBoundaryBFhZNsgt2fimstrE\r\nContent-Disposition: form-data; name', '"name"\r\n\r\nasdad\r\n------WebKitFormBoundaryBFhZNsgt2fimstrE--\r\n')])

But it doen`t lead to error, although I still need to get request.form["name"]. Tell me please, what am I doing wrong?

CodePudding user response:

Seems to be an issue with the axios version used. The data is sent with the wrong header and cannot be received properly even if the content-type-header is set manually.

Use the latest version and it should work.

from flask import (
    Flask,
    request
)

app = Flask(__name__)

@app.route('/')
def index():
    return app.send_static_file('index.html')

@app.post('/test')
def test():
    print(request.form)
    return '', 200
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <form @submit.prevent="submit">
        <input type="text" v-model="name" />
        <button type="submit">Add</button>
      </form>
    </div>
    <script>
      var app = new Vue({
        el: '#app',
        data: {
          name: '',
        },
        methods: {
          submit(event){
            let formData = new FormData();
            formData.append('name', this.name);
            axios({
              method: 'post',
              url: '/test',
              data: formData
            }).then(resp => console.log(resp))
              .catch(err => console.error(err));
          }
        },
      })
    </script>
  </body>
</html>
  • Related