Javascript onclick стрелял 4 раза - PullRequest
       0

Javascript onclick стрелял 4 раза

0 голосов
/ 21 сентября 2018

Форма входа должна отображать предупреждение, если пароль неверный.Тем не менее, он показывает предупреждение 4 раза.

Кнопка с id: 'loginbutton' запускает функцию 'auth ()' onclick.Работает нормально для входа и выхода.Но когда я пытаюсь ввести неправильное имя пользователя, пароль соединяется, предупреждающее сообщение window.alert («Неверное имя пользователя или пароль») показывается четыре раза один за другим.Это означает, что событие onclick () по какой-то причине запускается четыре раза.

Здесь та же кнопка входа в систему также работает как кнопка выхода из системы.Я использую функцию setLoginButton (), чтобы определить текущее состояние пользователя (вошел или нет) и обновить текст кнопки, основываясь на этом.

HTML:

<body onload = "setLoginButton()">
<nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Lorem</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <form class="navbar-form navbar-right">
            <div class="form-group">
              <input type="text" placeholder="Username" class="form-control" id="username">
            </div>
            <div class="form-group">
              <input type="password" placeholder="Password" class="form-control" id="password">
            </div>
            <button type="submit" class="btn btn-success" onclick="auth(event)" id="loginbutton">Sign in</button>
          </form>
        </div><!--/.navbar-collapse -->
      </div>
    </nav>

Javascript:

// Init datatables
$(document).ready( function () {
    $('#content1').DataTable();
    $('#holdTable').hide();
} );


function setLoginButton() {
    token = window.sessionStorage.getItem('cicitoken');
    if (token == null) {
        return false;
    }
    else {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 400) {
                window.sessionStorage.removeItem('cicitoken');
                buttonText = "Sign In";
                displayForm = "block";
            } 
            else {
                buttonText = "Sign Out";
                displayForm = "none";
            }
            document.getElementById("loginbutton").innerHTML = buttonText;
            document.getElementById("username").style.display = displayForm;
            document.getElementById("password").style.display = displayForm;
        };
        xhttp.open("POST", "/api-token-verify/", true);
        xhttp.setRequestHeader("Content-type", "application/json");
        xhttp.send(JSON.stringify({"token": token}));
    }
}


//auth function to get token and use sessionstorage
auth = function(e) {
    e.preventDefault();

    token = window.sessionStorage.getItem('cicitoken');
    if ( token != null) {
        window.sessionStorage.removeItem('cicitoken');
        location.reload()
    }
    else {
        var xhttp = new XMLHttpRequest();
        jdata={username:document.getElementById("username").value,password:document.getElementById("password").value};
        xhttp.onerror = function(xhr, status, err) {
            console.log(err);
        }
        xhttp.onabort = function(xhr, status, err) {
            console.log(err);
        }
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState==4 && xhttp.status==200) {
                var response = JSON.parse(xhttp.responseText);
                window.sessionStorage.setItem('cicitoken',response.token);
            }
            else {
                window.alert("Wrong username or password");
                setLoginButton();
            }
            setLoginButton();
        }

        xhttp.open("POST", "/api-token-auth/", true);
        xhttp.setRequestHeader("Content-type", 'application/json; charset=UTF-8');
        xhttp.send(JSON.stringify(jdata));
    }
}

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Для тех, кто сталкивается с той же проблемой, вот как я изменил код в соответствии с ответом @Shilly:

    xhttp.onreadystatechange = function() {
        if (xhttp.readyState==4 && xhttp.status==200) {
            var response = JSON.parse(xhttp.responseText);
            window.sessionStorage.setItem('cicitoken',response.token);
            setLoginButton();
        }
        else if (xhttp.readyState==4 && xhttp.status==400){
            window.alert("Wrong username or password");
            setLoginButton();
        }
    }
0 голосов
/ 21 сентября 2018

XMLHttpRequest будет перебирать их состояния готовности.Таким образом, он начинается в состоянии 0 и будет проходить через каждое состояние, пока не будет завершен до состояния 4.

Поскольку ваше оповещение связано с событием onreadystatechange, это событие также будет вызываться 4 раза:

xhttp.onreadystatechange = function() {
    if (xhttp.readyState==4 && xhttp.status==200) {
        var response = JSON.parse(xhttp.responseText);
        window.sessionStorage.setItem('cicitoken',response.token);
    }
    else {
        window.alert("Wrong username or password");
        setLoginButton();
    }            
    setLoginButton();
}

Поскольку предупреждение связано с условием: if readyState !== 4, оно будет отображать предупреждение для состояний 0, 1, 2 и 3.

Решение состоит в том, чтобы включить предупреждение в if readyState === 4 блок где-то вместо того, чтобы иметь его снаружи.Затем вы также можете привязать предупреждение к событию onerror XMLHttpRequest, чтобы перехватить ошибки, если XMLHttpRequest завершится неудачно, прежде чем он достигнет readyState 4.

Это также подразумевает, что все изменения стилей, которые вы делаете в другом обработчике readystatechange, такжевызывается слишком часто, а не только тогда, когда известен результат запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...