return redirect() not displaying the new page in the browser, after sending data from JavaScript file to Python (Flask)

Question:

I’m trying to make a form where JavaScript makes the authentication of it. After JavaScript says that the user followed the rules correctly, the JavaScript file collects the data typed by the user, so the data is sent to Python (with the help of ajax). From the Python file, I want that it recognizes the data and finally redirect to a new page.
Now, I am having an issue because after Python recognizes the previously shared data, return redirect() is not working. It’s strange, even though I tried with return redirect(url_for()), I got the same result. The browser does not update the new page.

Inside templates folder >>

educateForm.html

<!DOCTYPE html>

<html lang="en">

    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">

        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

        <!--Icon link-->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">

        <title>Educate Form</title>
    </head>

    <body>


        <div class="container-fluid padding" id="fullForm1">
            <div class="row padding">
                <div class="col-md-12 col-lg-12">
                <div class="centerForm" style="text-align:left;">
                    <h2>Contact information: </h2>

                <!--Form-->
                    <form name='registration' action="/educateForm" method="post"><!--method="post" onsubmit="return formValidation()"-->
                        <!--onsubmit="return false"-->
                        <div class="row">
                            <div class="col-md-5">
                                <label for="FName" class="form-label">First name</label>
                                <input type="text" name="FName" placeholder="Mark" id="FName" class="form-control" required="required" autocomplete="off"/>
                            </div>
                            <div class="col-md-5">
                                <label for="LName" class="form-label">Last name</label>
                                <input type="text" name="LName" placeholder="Smith" id="LName" class="form-control" required="required" autocomplete="off"/>
                            </div>

                        </div>

                        <div class="row">
                            <div class="col-md-5">
                                <label for="email" class="form-label">Email address</label>
                                <input type="email" name="email" id="email" placeholder="[email protected]" class="form-control" aria-describedby="emailHelp" required="required" autocomplete="off">
                            </div>
                        </div>

                        <!--DISPLAY NONE - STYLE-->
                        <div class="row" style="display: none;">
                            <div class="col-md-10">
                                <label for="skillsLabel" class="form-label">What are your skills?</label>
                                <textarea class="form-control" name="skillsText" id="skillsText" style="height: 100px" required="required" autocomplete="off"></textarea>
                            </div>
                        </div>

                            <div id="buttonContainer">
                                <input id="orderButton" type="submit" name="submit" class="btn btn-primary" value="NEXT" onClick="return formValidation();" />
                                <input id="resetButton" type="reset" name="reset" class="btn btn-outline-secondary" value="Clear Form" onClick="return confirmreset()" />
                            </div>

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


        <!--Pagination-->
        <ul class="pagination justify-content-center" id="pagination">
            <li class="page-item disabled">
              <a class="page-link">Previous</a>
            </li>
            <li class="page-item active"><a class="page-link" href="/educateForm">1</a></li>
            <li class="page-item"><a class="page-link" href="/educateForm2">2</a></li>
            <li class="page-item">
              <a class="page-link" href="/educateForm2">Next</a>
            </li>
        </ul>


        <!--<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>-->
        <!--<script src="/educate"></script>-->

        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
        <!--Doesn't recognizes AJAX ⏬-->
        <!--<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>-->

        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>

        <script src="/educate"></script>
    </body>
</html>

educateForm2.html

<!DOCTYPE html>

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

        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">

        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

        <!--Icon link-->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">

        <title>Educate 2</title>

    </head>
    <body>


        <div class="container-fluid padding">
            <div class="row welcome text-center">
                <div id="properties" class="col-12">
                    <h1 class="display-4">Page 2</h1>
                </div>
            </div>
        </div>


        <!--Pagination-->
        <ul class="pagination justify-content-center" id="pagination">
            <li class="page-item">
            <a class="page-link" href="educateForm">Previous</a>
            </li>
            <li class="page-item"><a class="page-link" href="educateForm">1</a></li>
            <li class="page-item active"><a class="page-link" href="educateForm2">2</a></li>
            <li class="page-item disabled">
            <a class="page-link">Next</a>
            </li>
        </ul>


        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
        <!--Doesn't recognizes AJAX ⏬-->
        <!--<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>-->

        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>

    </body>
</html>

educate.js

"use strict";


function formValidation() {

    var emailRegex = /^[A-Za-z0-9._]*@[A-Za-z]*.[A-Za-z]{2,5}$/; // Expression for validating email

    var fname = document.registration.FName.value;
    var lname = document.registration.LName.value;
    var email = document.registration.email.value;


    if (fname == "") {
        alert('Enter the first name!');
        document.registration.FName.focus();
        return false;
    }

    if (lname == "") {
        document.registration.LName.focus();
        alert('Enter the last name!');
        return false;
    }

    if (email == "") {
        document.registration.email.focus();
        alert('Enter the email!');
        return false;
    }

    if (!emailRegex.test(email)) {
        alert('Re-enter the valid email in this format: [[email protected]]');
        document.registration.email.focus();
        return false;
    }


    if (fname != '' && lname != '' && email != '') // condition for check mandatory all fields
    {
        let confirmation = "Once you submit this form, you can't go back nAre you sure you want to leave this page?";
        if (confirm(confirmation) == true) {
            const dict_values = {fname, lname, email} //Pass the javascript variables to a dictionary.
            const s = JSON.stringify(dict_values); // Stringify converts a JavaScript object or value to a JSON string
            console.log(s); // Prints the variables to console window, which are in the JSON format
            window.alert(s);

            //Passing the data to Python (into "/educateForm" page) ⏬
            $.ajax({
                url:"/educateForm",
                type:"POST",
                contentType: "application/json",
                data: JSON.stringify(s)});

            //Display 2nd page without sharing data with Python⏬
            //var display = window.open("/educateForm2", "_self", "pagewin");
            //window.location.href = "/educateForm2";
        }
    }

}

function setUpPage(){
    formValidation();
}

window.addEventListener("load", setUpPage, false);

Outside templates folder >>

app.py

import json
import os

from flask import Flask, flash, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.security import check_password_hash, generate_password_hash

from flask import jsonify  # NEW
from flask import url_for


# Configure application
app = Flask(__name__)

# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)


@app.after_request
def after_request(response):
    """Ensure responses aren't cached"""
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response



@app.route("/educateForm", methods=["GET", "POST"])
def educateForm():
    """Show Educate Form(part 1)"""

    if request.method == "POST":
        output = request.get_json()
        print(output) # This is the output that was stored in the JSON within the browser
        print(type(output))
        result = json.loads(output) #this converts the json output to a python dictionary
        print(result) # Printing the new dictionary
        print(type(result))#this shows the json converted as a python dictionary

        #PROBLEM: Neither of both options worked ⏬
        #return redirect(url_for('educateForm2'))
        return redirect("/educateForm2")

    else:  # GET
        # Redirect user to educateForm.html
        return render_template("educateForm.html")

@app.route("/educateForm2", methods=["GET"])
def educateForm2():
    """Show Educate Form(part 2)"""
    if request.method == "GET":

        # Redirect user to educateForm2.html
        return render_template("educateForm2.html")

@app.route("/educate")
def educate():
    """Show educate.js"""
    if request.method == "GET":

        # Redirect user to educate.js
        return render_template("educate.js")


if __name__ == "__main__":
    app.run()
Asked By: Kmi4444

||

Answers:

What happens here is that you are making a post request, so the return from the server will not be a redirect in the browser but a response to your javascript request. In that case, you can handle the response in javascript by sending some sort of status_code through the server.
Example:

@app.route("/educateForm", methods=["GET", "POST"])
def educateForm():
    """Show Educate Form(part 1)"""

    if request.method == "POST":
        output = request.get_json()

        # validate here the post
        ...

        # is valid ?
        return Response(status=200)
        
        #is not valid
        return Response(status=422)

And in javascript get the status code of the response and redirect the user to the page you want

        if (confirm(confirmation) == true) {
            const dict_values = {fname, lname, email} //Pass the javascript variables to a dictionary.
            const s = JSON.stringify(dict_values); // Stringify converts a JavaScript object or value to a JSON string

            //Passing the data to Python (into "/educateForm" page) ⏬
            const response = $.ajax({
                url:"/educateForm",
                type:"POST",
                contentType: "application/json",
                data: JSON.stringify(s)});

            //Display 2nd page without sharing data with Python⏬
            //var display = window.open("/educateForm2", "_self", "pagewin");
            if(response.status === 200) window.location.href = "/educateForm2";
            else alert('Form not valid')
        }
Answered By: Lucas Emanuel

Finally, I got the second page. For those folks who maybe are going through a similar issue. I want to share my code:

educate.js

    if (fname != '' && lname != '' && email != '') // condition for check mandatory all fields
    {
        let confirmation = "Once you submit this form, you can't go back nAre you sure you want to leave this page?";
        if (confirm(confirmation) == true) {
            const dict_values = {fname, lname, email} //Pass the javascript variables to a dictionary.
            const s = JSON.stringify(dict_values); // Stringify converts a JavaScript object or value to a JSON string
            console.log(s); // Prints the variables to console window, which are in the JSON format
            window.alert(s);

            //Passing the data to Python (into "/educateForm" page) ⏬
            $.ajax({
                url:"/educateForm",
                type:"POST",
                contentType: "application/json",
                data: JSON.stringify(s)});

            //Get the URL
            var urlPath = window.location.origin+window.location.pathname;
            console.log(urlPath);

            //Using response status 
            fetch(urlPath)
                .then(response => {
                    console.log('response.status: ', response.status); //  ️ 200 (from "GET")
                    console.log(response);
                    if(response.status == 200) {
                        window.location.href = "/educateForm2";
                    }
                })
                .catch(err => {
                    console.log(err);
                    alert('Form not valid');
                });

        }
    }

app.py

@app.route("/educateForm", methods=["GET", "POST"])
def educateForm():
    """Show Educate Form(part 1)"""

    if request.method == "POST":
        output = request.get_json()
        result = json.loads(output) #this converts the json output to a python dictionary


        #PROBLEM SOLVED: ⏬
        if len(result) == 0:
            print('This dictionary is empty!')
            return jsonify({"result" : "failure", "error" : "401", "message" : "Empty Dictionary."}), 401
        else:
            print('This dictionary is not empty!')
            return jsonify({"result": "success"}), 200


    elif request.method == "GET": # GET
        # Redirect user to educateForm.html
        return render_template("educateForm.html")
Answered By: Kmi4444
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.