DrDoom
DrDoom

Reputation: 325

Cant get vanilla JS onreadystatechange function / readyState 4 to work

I'm making a "log in" page for a HotSpot. Once a user inputs his/her email, they gain internet access.

To make this work, I'm using two AJAX functions.

  1. After clicking submit, username and password are sent to the router (which grants the user internet access)
  2. The 2cnd AJAX call is made, which saves the email to the database (after the user gets internet access (it should be sent right after he gets internet access and before he gets redirected)).

Currently, I'm having trouble getting ...

xhr.onreadystatechange = function () { var DONE = this.DONE || 4; if (xhr.readyState === XMLHttpRequest.DONE){

... function to work.

Ajax calls are made to early, the user gets instantly redirected and emails are not saved in the database (I assume it's becouse they are sent before the user has internet access).

Any help you could give me will be much appriciated.

HTML document

<!DOCTYPE html>
<html>
<head>
<meta content="text/html" />
<meta charset="utf-8" />

<title>HotSpot</title>

</head>
<body>

    <!-- Email Form, which gets saved into the DB -->
    <form accept-charset="utf-8" name="mail" onsubmit="return false;" method="post" id="mail">
        <h1>Hotspot</h1>
        <h2>To gain internet access, enter your email.</h2>
        <br />
        <input type="text" id="email" name="email" autofocus="autofocus" />
        <br />
        <input type="submit" value="Submit" id="submit_ok" name="submit_ok" /> <br />
    </form>

<script type="text/javascript">

document.getElementById("submit_ok").addEventListener("click", SendAjax);
function SendAjax() {
    var email = document.getElementById("email").value;
    console.log(email);
    // Check if fields are empty 
    if (email=="") {
        alert("Please enter your email.");
    }
    // AJAX code to submit form
    else{
        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://router/login', true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
        xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");

        xhr.onreadystatechange = function () {
            var DONE = this.DONE || 4;
            if (xhr.readyState === XMLHttpRequest.DONE){
                var xhr2 = new XMLHttpRequest();
                xhr2.open('POST', 'http://server/insertDB.php', true);
                xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
                var useremail = document.getElementById("email").value;
                xhr2.send("Email="+encodeURIComponent(useremail));

                xhr2.onreadystatechange = function () {
                var DONE = this.DONE || 4;
                    if (xhr2.readyState === XMLHttpRequest.DONE) {
                        location.href = "http://server/redirected.html";
                    }
                };
            }
        }
    }
}

This has also been tried, but it doesen't work.

            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://router/login', true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
            xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
            xhr.onreadystatechange = function () {
            var DONE = this.DONE || 4;
                  if (this.readyState === DONE){
                    etc etc
                  }

PHP document (I don't think it matters for this instance, but you know... just in case)

<?php

    require ('connect.php');

    $clean_email = "";
    $cleaner_email = "";


    if(isset($_POST['email']) && !empty($_POST['email'])){
        //sanitize with filter
        $clean_email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
        //sanitize with test_input
        $cleaner_email = test_input($clean_email);
        //validate with filter
        if (filter_var($cleaner_email,FILTER_VALIDATE_EMAIL)){
            // email is valid and ready for use
            echo "Email is valid";  
            //Email is a row inside the database
            $stmt = $DB->prepare("INSERT INTO addresses (Email) VALUES (?)");
            $stmt->bind_param("s", $cleaner_email);
            $stmt->execute();
            $stmt->close();
        } else {
            // email is invalid and should be rejected
            echo "Invalid email, try again";
        } 
    } else {
    echo "Please enter an email";
    }

    function test_input($data) {
      $data = trim($data);
      $data = stripslashes($data);
      $data = htmlspecialchars($data);
      return $data;
    }

    $DB->close();   
?>

Edit:

Pasting a snippet of the code, which is changed.

        else{
            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://router.login', true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
            xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");

            var xhr2= new XMLHttpRequest();

            var useremail = document.getElementById("email").value;
            xhr.onreadystatechange = function () {
            console.log(DONE);
            var DONE = this.DONE || 4;
                if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
                    console.log(DONE);              
                    console.log(xhr.status);
                    xhr2.open('POST', 'http://server.insertDB.php', true);
                    xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
                    xhr2.send("Email="+encodeURIComponent(useremail));                  
                }
            }
            xhr2.send("Email="+encodeURIComponent(useremail));  
        }
    }

I needed to move the email variable outside, otherwise I was getting an error that it isn't defined.

I'm getting an error on xhr2.send now...

Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED. at HTMLInputElement.SendAjax

Upvotes: 1

Views: 593

Answers (1)

Pjotr Raskolnikov
Pjotr Raskolnikov

Reputation: 1688

You have to set your listener BEFORE sending the request. Here an exapmle using the onload listener

    // Set up our HTTP request
    var xhr = new XMLHttpRequest();

    // Setup our listener to process completed requests
    xhr.onload = function () {

        // Process our return data
        if (xhr.status >= 200 && xhr.status < 300) {
            // What do when the request is successful
            console.log('success!', xhr);
        } else {
            // What do when the request fails
            console.log('The request failed!');
        }

        // Code that should run regardless of the request status
        console.log('This always runs...');
    };

    // Create and send a GET request
    // The first argument is the post type (GET, POST, PUT, DELETE, etc.)
    // The second argument is the endpoint URL
    xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts');
    xhr.send();

Here an example with the ready state change listener

    xhr.open(method, url, true);
    xhr.onreadystatechange = function () {
        if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
            console.log(xhr.responseText);
        }
    };
    xhr.send();

Here is your code with the right calling order

function SendAjax() {
    var email = document.getElementById("email").value;
    console.log(email);
    // Check if fields are empty 
    if (email=="") {
        alert("Please enter your email.");
    }
    // AJAX code to submit form
    else{
        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://router/login', true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");

        xhr.onreadystatechange = function () {
            var DONE = this.DONE || 4;
            if (xhr.readyState === XMLHttpRequest.DONE){
                var xhr2 = new XMLHttpRequest();
                xhr2.open('POST', 'http://server/insertDB.php', true);
                xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
                var useremail = document.getElementById("email").value;

                xhr2.onreadystatechange = function () {
                    var DONE = this.DONE || 4;
                    if (xhr2.readyState === XMLHttpRequest.DONE) {
                        location.href = "http://server/redirected.html";
                    }
                };
                xhr2.send("Email="+encodeURIComponent(useremail));
            }
        }

        xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
    }
}

Upvotes: 1

Related Questions