如何在发送新请求时取消AJAX请求?

时间:2016-06-09 09:02:07

标签: javascript ajax

我知道之前已经提出了类似的问题,但是尽管已经阅读了足够多的问题,我还是没有设法解决我的问题。

我正在创建用户名输入,我使用AJAX从服务器检索响应,具体取决于已使用的用户名。


我的JavaScript代码:

var timer = null;
var passed4Before = false;
var xhttp = null;
var ajaxInProgress = false;
var username = document.getElementById("username");

username.onkeyup = function(e) {

  // Check if username exists in the database
  function usernameExists(value) {
    if (keypressed.match(/[a-z0-9-_]/gi) || e.which === 8 || e.which === 46) {
      clearTimeout(timer);
      ajaxInProgress = true;
      timer = setTimeout(function() {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
          if (xhttp.readyState === 4 && xhttp.status === 200) {
            document.getElementById("div").innerHTML = xhttp.responseText;
          }
        };
        xhttp.open("POST", "php.php", true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send("username=" + value);
      }, 1500);
    }
  };

  if (this.value.length >= 4) {
    // Check if user has typed above 4 characters
    passed4Before = true;
  }

  // AN ATTEMPT TO ABORT THE AJAX REQUEST WHILE IT HAS STARTED THAT HAS FAILED
  // RESULT: THE AJAX DOESN'T WORK AT ALL
  if (ajaxInProgress) {
    xhttp.abort();
    ajaxInProgress = false;
  }


  if (this.value.length < 4) {
    if (passed4Before) {
      console.log("The username cannot be less than 4 characters");
      passed4Before = false;
      // To stop ajax request of the previous key press (if it  hasn't started yet)
      clearTimeout(timer);
    }
  } else {
    usernameExists(this.value);
  }
};



我100%肯定我不得不使用xhttp.abort(),但我还没有发现。

我正在使用ajaxInProgress变量来确定是否存在活动的AJAX请求,如果有,当我再次键入时,它必须停止并检查我的输入的新值。

当前形式的代码没有实现这一点,相反,它要么永远不会发出一个AJAX请求,要么发送一个然后停止。

我更喜欢没有任何第三方插件的JavaScript解决方案。任何帮助将不胜感激。

[已解决](包括Gilad Artzi的回答):

对于将来可能需要的人,编辑的功能是:

function usernameExists(value) {
    if (keypressed.match(/[a-z0-9-_]/gi) || e.which === 8 || e.which === 46) {
        if (xhttp) {
            xhttp.abort();
        }
        xhttp = new XMLHttpRequest();
        clearTimeout(timer);
        timer = setTimeout(function() {
            xhttp.onreadystatechange = function() {
                if (xhttp.readyState === 1) {
                    document.getElementById("loader1").innerHTML = "<img src = \"../../Content/Images/ajax-loader.gif\"/>";
                }
                else if (xhttp.readyState === 4 && xhttp.status === 200) {
                    document.getElementById("loader1").innerHTML = "<img class = \"invisible\" src = \"../../Content/Images/ajax-loader.gif\"/>";
                    document.getElementById("tip1").innerHTML = xhttp.responseText;
                    if (xhttp.responseText.indexOf("unavailable") > 0) {
                        username_label.style.color = "red";
                    }
                    else {
                        username_label.style.color = "green";
                    }
                }
            };
            xhttp.open("POST", "Register.php", true);
            xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhttp.send("username=" + value);
        }, 1500);
    }
};

2 个答案:

答案 0 :(得分:4)

您应该保留对您的有效XMLHttpRequest的引用,如果您开了一个新引用,请使用前一个abort方法。

更具体地说,在您的代码中,在xhttp回调中声明setTimeout var而不是xhttp = new XMLHttpRequest();回调内部,并在创建新的XHR(if (xhttp) { xhttp.abort(); } xhttp = new XMLHttpRequest(); )之前简单地中止前一个,如果存在:

_id

答案 1 :(得分:0)

timer = setTimeout(function() {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
          if (xhttp.readyState === 4 && xhttp.status === 200) {
            document.getElementById("div").innerHTML = xhttp.responseText;
          }
        };

在这里,您要创建局部变量xhttp(使用var关键字)。在这里删除var关键字。

var xhttp = new XMLHttpRequest();

并验证xhttp变量

// AN ATTEMPT TO ABORT THE AJAX REQUEST WHILE IT HAS STARTED THAT HAS FAILED
  // RESULT: THE AJAX DOESN'T WORK AT ALL
  if (ajaxInProgress && xhttp) {
    xhttp.abort();
    ajaxInProgress = false;
  }