flask error: werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand

Viewed 31

To create a sign up page, I ask to the user his informations (name, surname, email, password), then I put this info on my database, but it always save as NULL. (I use DB browser). I search a lot to solve this, I tried all I found, but nothing solved this. This is my HTML script:

<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
</head>
<body>
    <nav class="navbar navbar-expand-lg bg-light">
        <div class="container-fluid">
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" href="/login">Login</a>
                  </li>
            </ul>
        </div>
        </div>
    </nav>
    <div class="container">
      <div class="row">
        <div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
          <div class="card border-0 shadow rounded-3 my-5">
            <div class="card-body p-4 p-sm-5">
              <h5 class="card-title text-center mb-5 fw-light fs-5">Sign up</h5>
              <form method="post" class="m-5">
                  <div class="form-floating mb-3">
                  <input type="text" class="form-control" id="floatingInput1" placeholder="Name"
                         required="required" value="{{ request.form['name'] }}">
                  <label for="floatingInput1">Name</label>
                </div>
                  <div class="form-floating mb-3">
                  <input type="text" class="form-control" id="floatingInput2" placeholder="Surname"
                         required="required" value="{{ request.form['surname'] }}">
                  <label for="floatingInput2">Surname</label>
                </div>
                <div class="form-floating mb-3">
                  <input type="email" class="form-control" id="floatingInput3" placeholder="name@example.com"
                  required="required" value="{{ request.form['email'] }}">
                  <label for="floatingInput3">Email</label>
                </div>
                <div class="form-floating mb-3">
                  <input type="password" class="form-control" id="floatingPassword" placeholder="Password"
                  required="required" value="{{ request.form['password'] }}">
                  <label for="floatingPassword">Password</label>
                </div>

                <div class="form-check mb-3">
                  <input class="form-check-input" type="checkbox" value="" id="rememberPasswordCheck">
                  <label class="form-check-label" for="rememberPasswordCheck">
                    Remember password
                  </label>
                </div>
                <div class="d-grid">
                  <button class="btn btn-primary btn-login text-uppercase fw-bold" type="submit">Registrati</button>
                </div>
                  <div class="text-center">

      </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script>
</body>
</html>

And this is the python script:

import sqlite3

from flask import Flask, render_template, request, redirect

app = Flask(__name__)

def connect_db():
    connection = sqlite3.connect('users.db')
    connection.row_factory = sqlite3.Row
    return connection

@app.route('/')
def index():
    connection = connect_db()
    posts = connection.execute('SELECT * FROM posts').fetchall()
    connection.close()
    return render_template('index.html', posts=posts)

@app.route('/login')
def login():
    return render_template('login.html')

@app.route('/signup', methods=('GET','POST'))
def signup():
    if request.method == 'POST':
        name = request.form['name']
        surname = request.form['surname']
        email = request.form['email']
        password = request.form['password']
        connection = connect_db()
        connection.execute(
            'INSERT INTO posts (name, surname, email, password) VALUES (?,?,?,?)',
            (name, surname, email, password)
        )
        connection.commit()
        connection.close()
        return redirect('/')
    return render_template('signup.html')

if __name__ == "__main__":
    from waitress import serve
    serve(app, host="0.0.0.0", port=8080)

This is the screenshot of the error: flask error and this is the screenshot of the database: database result

1 Answers

You're not setting the id on your form inputs to match the keys for request.form, it's a dict and it's keys are made up of the id's from the html inputs. You've used the id floatingInput1 for the name input in your html, so when you try access your form data with request.form['name'] you're getting the BadKey error.

So either change the line for getting your data to request.form.get('floatingInput1') or change your html inputs to use <input type="text" id="name" name="name">

Related