2009-07-27 2 views
-1

Я использую следующий скрипт для проверки того, могу ли я подключаться к веб-сайту в регулярном интервале (10 секунд в моем примере кода). Я встретился с двумя проблемами, с любыми идеями, как их решить?Javascript XMLHttpRequest issue

  1. Если веб-сайт очень медленно, и нет ответа в течение 10 секунд (что делает PingWebSite не вернуться), я нахожу 2 второй вызов PingWebSite будет выполнен из 10 второго интервала прибывает. Моя цель заключается в том, что я хочу, чтобы только один вызов PingWebSite выполнялся, и если выполняется 10-секундный интервал и выполняется предыдущий PingWebSite, я хочу предотвратить выполнение текущего PingWebSite. Есть идеи, как это решить?

  2. Я нахожу странную проблему, когда подключаюсь к очень медленному веб-сайту, и путь кода выполняется для «alert (« connect »);», то я ожидаю, что исключение будет выбрано для таймаута, но в моей отладке , исключение не выбрасывается. Любые идеи, как поймать исключение тайм-аута?

Вот мой код,

var index = 0; 

function setup() { 
    window.setInterval(PingWebSite, (10 * 1000)); 
} 

function PingWebSite() { 

    var http_request = new XMLHttpRequest(); 
    try { 
     http_request.open("GET", "http://www.google.com", true); 
     http_request.onreadystatechange = function() { 
      if (http_request.readyState == 4) { 
       if (http_request.status == 200) { 
        MonitorInformation.innerText = "http://www.google.com" + " Connection ok"; 
        alert("ok"); 
       } 
       else { 
        alert("fail"); 
       } 
       http_request = null; 
      } // if if (http_request.readyState == 4) 
      else { 
       // if execute here, no exception will be thrown 
       alert("connecting"); 
      } 
     } // end of function 
     http_request.send(null); 
    } // try 
    catch (e) { 
     alert("service is not available"); 
    } 
} 

EDIT 1: Я последовал совету здесь, чтобы изменить свой код. Вот приведенная ниже версия. Новая проблема - значение индекса (например, 0) будет выведено в поле предупреждающего сообщения перед окном сообщения об ошибке/сбое. Я думаю, что значение индекса (например, 0) должно быть предложено в окне предупреждений после сообщения об ошибке/сбое сообщения об ошибке. Любые идеи почему?

var index = 0; 
var http_request; 
var xhrTimeout; 
var chkConn; 

function setup() { 
    chkConn = window.setInterval(PingWebSite, (10 * 1000)); 
} 

function WebMonitorTimeout() { 
    http_request.abort(); 
    alert("timeout"); 
    index = index + 1; 
} 

function PingWebSite() { 

    http_request = new XMLHttpRequest(); 
    http_request.open("GET", "http://www.google.com", true); 

    http_request.onreadystatechange = function() 
    { 
     if (http_request.readyState == 4) { 
      if (chkConn) { clearInterval(chkConn); } 
      if (http_request.status == 200) { 
       alert("ok"); 
       index = index + 1; 
       if (xhrTimeout) { clearTimeout(xhrTimeout); } 
      } 
      else { 
       alert("fail"); 
       index = index + 1; 
       if (xhrTimeout) { clearTimeout(xhrTimeout); } 
       } 

       http_request = null; 
      } //if (http_request.readyState == 4) 

    } // end of event function 
    http_request.send(null); 
    xhrTimeout = setTimeout("WebMonitorTimeout();", 30000); 
    alert(index); 
    chkConn = window.setInterval(PingWebSite, (30 * 1000)); 
} 

спасибо заранее, Джорджа

ответ

1

Для вашей первой проблемы, не используйте setIntervalsetTimeout использования в функции обратного вызова для запроса:

http_request.onreadystatechange = function() { 
    if (http_request.readyState == 4) { 
     // ... 
     setTimeout(PingWebSite, 10000); 
    } 
}; 

Не забудьте позвонить ваша функция после того, как она была определена для ее запуска (после этого setTimeout будет вызываться каждый раз после завершения запроса.)

Обратите внимание, что в некоторых случаях вы, возможно, не достигнете readyState 4. Я действительно не изучал, как другие библиотеки обрабатывают эти случаи, но посмотрите на the source code of jQuery, например, для вдохновения.

+0

Благодаря Blixt 1. но если я не называю setInterval, как убедиться, что я пинг Интернет сайта в регулярном интервале? Мне нужно регулярно пинговать веб-сайт, а не только один раз. 2. Когда вызывается onreadystatechange? Только когда мы позвоним? – George2

+1

1) «setTimeout» будет проверять, что функция «PingWebSite» вызывается регулярно. Он не будет вызываться ровно каждые 10 секунд, потому что это вызовет проблемы, которые у вас были. Вместо этого он будет называться через 10 секунд после завершения предыдущего запроса. Поэтому, если все запросы занимают 1 секунду, чтобы закончить в среднем, «PingWebSite» будет вызываться каждые 11 секунд в среднем. Это так, что даже если запрос занимает 20 секунд, он все равно будет ждать 10 секунд, прежде чем делать следующий запрос, вместо того, чтобы начинать два новых запроса, пока первый запрос еще не закончен. – Blixt

+1

2) 'onreadystatechange' будет вызываться большую часть времени, хотя в случае таймаута или других сетевых проблем он может не достигнуть состояния 4. Чтобы решить эту проблему, многие фреймворки ждут определенное количество секунд, прежде чем вызывать' http_request.abort() 'и запуск ошибки« тайм-аута ». См. Источник jQuery, или пример Рамиза Уддина. – Blixt

2

Дубликат javascript connect to web site code not working

Вы не можете сделать Cross Site XHR запросы из-за браузера безопасности

+0

ReadyState не будет срабатывать, потому что линия выше остановится из-за безопасности. Такая же политика происхождения остановит выполнение сценария – AutomatedTester

+0

@David Я не верю, что он работает в домене Google, поэтому это не сработает. – AutomatedTester

+0

Он может работать с google.com без каких-либо проблем. Как вы думаете, почему мой вопрос связан с безопасностью на разных площадках? :-) – George2

1
<SCRIPT language=javascript> 
// Needed for IE6 and older to replicate the standard XMLHttpRequest object 
if (window.ActiveXObject && !window.XMLHttpRequest){window.XMLHttpRequest = 
function(){progIds=new Array("Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.5.0", 
"Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP", 
"Microsoft.XMLHTTP");for(i in progIds){try{return new 
ActiveXObject(progIds[i]);}catch(ex){alert(progIds[i]);}}return null;};} 

// Standard asynchonous AJAX code 
var xhr = new XMLHttpRequest(); 
// You would normally trade out the location.href with an actual .ashx 
// page. It's like this here only for testing, thereby requesting this 
// same page back from the server. 
xhr.open("POST",location.href,true); 

// The function that will be called asynchronously when the server sends 
// back its response 
xhr.onreadystatechange=function(){ 
    // If you're using the file system instead of a web server then xhr.status 
    // will come back as 0, not 200. And of course if the page isn't found 
    // then a web server will send back a status of 404. xhr.readyState is 4 
    // when the page is done. 
    if (xhr.readyState == 4 && xhr.status == 200) { 
     clearTimeout(xhrTimeout); // Looks like we didn't time out! 
     // Use xhr.responseText to parse the server's response 
     alert(xhr.responseText); 
    } 
} 

// Now that we're ready to handle the response, we can make the request 
xhr.send("My excellent post info"); 
// Timeout to abort in 5 seconds 
var xhrTimeout=setTimeout("ajaxTimeout();",5000); 
function ajaxTimeout(){ 
    xhr.abort(); 
    alert("Well dang, the AJAX request timed out. Did you lose network "+ 
     "connectivity for some reason?"); 
    // Note that at this point you could try to send a notification to the 
    // server that things failed, using the same xhr object. 
} 
</SCRIPT> 
+1

У вас есть «предупреждение» в строке 7 в catch, которое может стать очень раздражающим. Я думаю, это осталось от отладки. – Boldewyn

+0

Спасибо Ramiz, отличный образец! 2 квазитонов. :-) 1. Я заметил, что в вашем коде вы не вызываете setInterval, мне нужно регулярно пинговать веб-сайт, а не только один раз, я смущен тем, как вы реализуете это в своем коде? 2. Когда будет вызвана функция, назначенная для onreadystatechange? Когда мы вызываем send on xhr или когда получен любой ответ от сервера? Вызывается функция, когда есть тайм-аут? – George2

+0

Другой вопрос: если код возврата с веб-сайта не 200, как ваш код справляется с этой проблемой? – George2