Flask 使用代码 400 响应所有 POST 请求

Flask responds to all POST requests with code 400

在基于 vue+flask 的项目上工作时,我遇到了一个与 POST-requests 相关的错误。 Flask 以代码 400 响应所有请求。要重现问题:

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(在模板目录中)

<!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>

按下按钮后,我得到代码 400。 192.168.1.67 - - [27/Apr/2022 17:18:23] "POST /test HTTP/1.1" 400 -

有调试:

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 显示此请求:click

在文本中:------WebKitFormBoundaryUG2BQoqdARJDgqg4 Content-Disposition: form-data;名称“名称”

dsadasdasd ------WebKitFormBoundaryUG2BQoqdARJDgqg4--

如果尝试打印 request.form,而不是 request.form["name"],我得到:

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

但这不会导致错误,尽管我仍然需要获取 request.form["name"]。 请告诉我,我做错了什么?

好像是使用的axios版本有问题。 数据发送错误header,即使手动设置content-type-header也无法正常接收

使用最新版本应该可以。

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/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/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>