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>