使用Javascript向服务器发送多个请求,直到服务器返回200

使用Javascript向服务器发送多个请求,直到服务器返回200,javascript,html,ajax,server,restart,Javascript,Html,Ajax,Server,Restart,我创建了一个html页面,用户在等待另一个应用程序重新启动时可以查看该页面。我创建了一个javascript脚本,它向应用程序发出多个请求,直到应用程序返回200。但是,当我试图打开html页面时,浏览器就会崩溃。有人能看到我的代码有什么问题吗 var responseStatus = 404; var numberOfTries = 0; var request = new XMLHttpRequest(); while(responseStatus != 200){ console

我创建了一个html页面,用户在等待另一个应用程序重新启动时可以查看该页面。我创建了一个javascript脚本,它向应用程序发出多个请求,直到应用程序返回200。但是,当我试图打开html页面时,浏览器就会崩溃。有人能看到我的代码有什么问题吗

var responseStatus = 404;
var numberOfTries = 0;
var request = new XMLHttpRequest(); 
while(responseStatus != 200){
    console.log("Checking if restart has completed. Attempt number: " + numberOfTries);
    request.open('GET', 'applicationurl', true);
    request.onreadystatechange = function(){
        if (request.readyState === 4){
            console.log("Request Status: " + request.status);
            responseStatus = request.status;
            console.log("Response Status: " + request.status);
            if (request.status != 200) {  
                numberOfTries++;
                console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries);
            }  
        }
    };
    request.send();
}
console.log("Server has successfully restarted");

您的方法会发送多个请求,但不会等待它们响应

以下是它的工作原理:

  • 将创建
    XMLHttpRequest
  • 一个回调和一个数据被分配给它
  • 此对象被发送到服务器
  • 然后,
    while
    循环结束并再次运行,而不是等待回调运行
结果,创建了大量
XMLHttpRequest
对象,同时运行了大量请求,这不是您想要的

您可以通过两种方式执行此操作:

  • 将其包装到函数中,并在失败时调用它(首选)
  • 设置一些等待响应的间隔
第一种方法:

function tryRequest(numAttempts) {
  var responseStatus = 404;
  var request = new XMLHttpRequest(); 

  console.log("Checking if restart has completed. Attempt number: " + numAttempts);
  request.open('GET', 'applicationurl', true);
  request.onreadystatechange = function(){
      if (request.readyState === 4){
          console.log("Request Status: " + request.status);
          responseStatus = request.status;
          console.log("Response Status: " + request.status);
          if (request.status != 200) {  
              console.log("Restart has not yet completed! NumberOfTries: " + numAttempts);
              tryRequest(numAttempts + 1)
          }  
      }
  };
  request.send();

  console.log("Server has successfully restarted");
}
tryRequest(0);
var responseStatus = 404;
var numberOfTries = 0;
var request = new XMLHttpRequest();
var interval = setInterval(tryRequest, 1000)

function tryRequest() {
  console.log("Checking if restart has completed. Attempt number: " + numberOfTries);
  request.open('GET', 'applicationurl', true);
  request.onreadystatechange = function(){
      if (request.readyState === 4){
          console.log("Request Status: " + request.status);
          responseStatus = request.status;
          console.log("Response Status: " + request.status);
          if (request.status != 200) {
              numberOfTries++;
              console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries);
          } else {
              clearInterval(interval);
              console.log("Server has successfully restarted");
          }
      }
  };
  request.send();
  }

}
第二种方法:

function tryRequest(numAttempts) {
  var responseStatus = 404;
  var request = new XMLHttpRequest(); 

  console.log("Checking if restart has completed. Attempt number: " + numAttempts);
  request.open('GET', 'applicationurl', true);
  request.onreadystatechange = function(){
      if (request.readyState === 4){
          console.log("Request Status: " + request.status);
          responseStatus = request.status;
          console.log("Response Status: " + request.status);
          if (request.status != 200) {  
              console.log("Restart has not yet completed! NumberOfTries: " + numAttempts);
              tryRequest(numAttempts + 1)
          }  
      }
  };
  request.send();

  console.log("Server has successfully restarted");
}
tryRequest(0);
var responseStatus = 404;
var numberOfTries = 0;
var request = new XMLHttpRequest();
var interval = setInterval(tryRequest, 1000)

function tryRequest() {
  console.log("Checking if restart has completed. Attempt number: " + numberOfTries);
  request.open('GET', 'applicationurl', true);
  request.onreadystatechange = function(){
      if (request.readyState === 4){
          console.log("Request Status: " + request.status);
          responseStatus = request.status;
          console.log("Response Status: " + request.status);
          if (request.status != 200) {
              numberOfTries++;
              console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries);
          } else {
              clearInterval(interval);
              console.log("Server has successfully restarted");
          }
      }
  };
  request.send();
  }

}
(免责声明:我当时并没有同时测试这两个方面)

您可以使用如下代码

var responseStatus = 404;
var numberOfTries = 0;
function check(){
        var request = new XMLHttpRequest(); 
        console.log("Checking if restart has completed. Attempt number: " + numberOfTries);
        request.open('GET', 'applicationurl', true);
        request.onreadystatechange = function(){
            if (request.readyState === 4){
               console.log("Request Status: " + request.status);
               responseStatus = request.status;
               console.log("Response Status: " + request.status);
               if (request.status != 200) {  
                  numberOfTries++;
                  console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries);
                   var tmp = setTimeout(function(){ check() },5000 ); // check after 5 second
               }  elseif (request.status == 200) {  
                    console.log("Server has successfully restarted");
               }
            }
        };
        request.send();

  }
//第一次打电话

check();
在我看来,最好的方法是结合@serge1peshcoff的两个选项。将调用编写为在响应失败时调用自身的函数,并在执行此操作时设置超时。在大多数情况下,您不希望在前一个请求之后立即发送另一个请求,您希望至少等待一秒或五秒以防止对服务器进行垃圾邮件发送(你也没有给出你期望的客户端数量。对你的浏览器有害的东西对服务器来说可能是可怕的,甚至在你的web应用程序完全启动并返回200个客户端之前,服务器可能正在处理请求)

此外,setTimeout是一种比setInterval更好的方法,因为您在每次往返时都会显式重置它

借用@serge:

function tryRequest(numTries) {
  var responseStatus = 404;
  var request = new XMLHttpRequest(); 
  numTries = numTries || 0;

  console.log("Checking if restart has completed. Attempt number: " + numAttempts);
  request.open('GET', 'applicationurl', true);
  request.onreadystatechange = function(){
      numTries++

      if (request.readyState === 4){
          console.log("Request Status: " + request.status);
          responseStatus = request.status;
          console.log("Response Status: " + request.status);
          if (request.status != 200) {  
              console.log("Restart has not yet completed! NumberOfTries: " + this.attempts);
              setTimeout(tryRequest.bind(null, numTries), 5000); // five seconds
          }  
      }
  };
  request.send();

  console.log("Server has successfully restarted");
}
tryRequest();

使用setTimeout方法在代码中添加延迟,您不断地使用访问服务器,而这就是为什么您的浏览器会崩溃。在第一次日志之后,控制台不会记录任何内容。浏览器冻结,我需要强制退出并重新打开浏览器以再次访问html页面。@rurounisergii再次,这是因为您在厕所中执行此操作p、 在一个请求成功之前,您实际上将发送数百个,甚至数千个请求。即使这样,即使您收到了200个请求,您也可能会提前发送数百个请求,因为您不等待它们返回,它们都是异步发送的。这是一个解决DDoS问题的好方法。并且使用带有异步调用的while循环是行不通的g开始工作。如果interval方法仍然打开,它应该中止调用。@epascarello是的,你是对的,我会更新答案为什么你不把
numtempts
作为
tryRequest
的参数传递给它?在我看来,这样做
this.attempts=this.attempts | 0;this.attempts++
是行不通的,因为在调用时ode>setTimeout,您将
TryAttests
传递给它而不带参数,并且
此操作。每次尝试
都将重新创建。在一定次数的尝试后,您如何使函数退出?更新我的代码以解释我通过传递参数引入的
范围问题。@rurounisergii要在一定次数的尝试后退出,只需设置测试并在再次调用setTimeout之前返回即可。