是否可以从Javascript ping服务器?

时间:2010-11-26 02:28:14

标签: javascript

我正在制作一个网络应用程序,要求我检查远程服务器是否在线。当我从命令行运行它时,我的页面加载时间达到了整整60秒(对于8个条目,它会随着更多的线性扩展)。

我决定在用户​​端进行ping操作。通过这种方式,我可以加载页面,让他们在浏览我的内容时等待“服务器在线”数据。

如果有人对上述问题有答案,或者他们知道解决方案以保持我的页面加载速度快,那我一定很感激。

17 个答案:

答案 0 :(得分:121)

我找到了一个通过非常巧妙地使用原生Image对象来完成此任务的人。

从他们的来源来看,这是主要功能(它依赖于源的其他部分,但你明白了。)

function Pinger_ping(ip, callback) {

  if(!this.inUse) {

    this.inUse = true;
    this.callback = callback
    this.ip = ip;

    var _that = this;

    this.img = new Image();

    this.img.onload = function() {_that.good();};
    this.img.onerror = function() {_that.good();};

    this.start = new Date().getTime();
    this.img.src = "http://" + ip;
    this.timer = setTimeout(function() { _that.bad();}, 1500);

  }
}

这适用于我测试过的所有类型的服务器(Web服务器,ftp服务器和游戏服务器)。它也适用于端口。如果有人遇到失败的用例,请在评论中发帖,我会更新我的答案。

更新:以前的链接已被删除。如果有人发现或实施上述内容,请发表评论,我会将其添加到答案中。

更新2 :@trante非常适合提供jsFiddle。

http://jsfiddle.net/GSSCD/203/

更新3 :@Jonathon创建了一个带有实现的GitHub仓库。

https://github.com/jdfreder/pingjs

更新4 :看起来这个实现不再可靠。人们还报告说Chrome不再支持所有内容,导致net::ERR_NAME_NOT_RESOLVED错误。如果有人可以验证替代解决方案,我会将其作为接受的答案。

答案 1 :(得分:17)

你可以试试这个:

ping.html 放在服务器上,有或没有任何内容,在javascript上执行如下操作:

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>

答案 2 :(得分:16)

Ping是ICMP,但如果远程服务器上有任何打开的TCP端口,则可以这样实现:

function ping(host, port, pong) {

  var started = new Date().getTime();

  var http = new XMLHttpRequest();

  http.open("GET", "http://" + host + ":" + port, /*async*/true);
  http.onreadystatechange = function() {
    if (http.readyState == 4) {
      var ended = new Date().getTime();

      var milliseconds = ended - started;

      if (pong != null) {
        pong(milliseconds);
      }
    }
  };
  try {
    http.send(null);
  } catch(exception) {
    // this is expected
  }

}

答案 3 :(得分:12)

你不能在javascript中直接“ping”。 可能还有其他一些方法:

  • 的Ajax
  • 使用带有isReachable
  • 的Java小程序
  • 编写一个服务器端脚本,用于ping和使用AJAX与您的serversidescript进行通信
  • 你也可以在flash(actionscript)中ping通

答案 4 :(得分:8)

您无法在浏览器Javascript中执行常规ping操作,但您可以通过例如从远程服务器加载图像来查明远程服务器是否处于活动状态。如果加载失败 - &gt;服务器关闭。

您甚至可以使用onload-event计算加载时间。这是example如何使用onload事件。

答案 5 :(得分:5)

为了保持您的请求快速,请缓存服务器端ping的结果,并每隔几分钟更新一次ping文件或数据库(或者您希望它是否准确)。您可以使用cron运行带有8个ping的shell命令并将输出写入文件,Web服务器会将此文件包含在您的视图中。

答案 6 :(得分:5)

使用websocket解决方案......

function ping(ip, isUp, isDown) {
  var ws = new WebSocket("ws://" + ip);
  ws.onerror = function(e){
    isUp();
    ws = null;
  };
  setTimeout(function() { 
    if(ws != null) {
      ws.close();
      ws = null;
      isDown();
    }
  },2000);
}

答案 7 :(得分:4)

标准ping的问题是它们是ICMP,a lot of places don't let through for security and traffic reasons。这可能解释了失败。

1.9之前的Ruby有一个基于TCP的ping.rb,它将与Ruby 1.9+一起运行。您所要做的就是将它从1.8.7安装复制到其他地方。我刚刚确认它会通过ping我的家用路由器来运行。

答案 8 :(得分:4)

如果您要查看的是服务器是否存在&#34;,您可以使用以下内容:

function isValidURL(url) {
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        isValid = data.query.results != null;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
}

这将返回true / false指示服务器是否存在。

如果您想要响应时间,可以稍作修改:

function ping(url) {
    var encodedURL = encodeURIComponent(url);
    var startDate = new Date();
    var endDate = null;
    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        if (data.query.results != null) {
            endDate = new Date();
        } else {
            endDate = null;
        }
      },
      error: function(){
        endDate = null;
      }
    });

    if (endDate == null) {
        throw "Not responsive...";
    }

    return endDate.getTime() - startDate.getTime();
}

用法很简单:

var isValid = isValidURL("http://example.com");
alert(isValid ? "Valid URL!!!" : "Damn...");

或者:

var responseInMillis = ping("example.com");
alert(responseInMillis);

答案 9 :(得分:2)

const ping = (url, timeout = 6000) => {
  return new Promise((reslove, reject) => {
    const urlRule = new RegExp('(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]');
    if (!urlRule.test(url)) reject('invalid url');
    try {
      fetch(url)
        .then(() => reslove(true))
        .catch(() => reslove(false));
      setTimeout(() => {
        reslove(false);
      }, timeout);
    } catch (e) {
      reject(e);
    }
  });
};

使用如下:

ping('https://stackoverflow.com/')
  .then(res=>console.log(res))
  .catch(e=>console.log(e))

答案 10 :(得分:2)

这里有许多疯狂的答案,特别是关于CORS -

您可以执行http HEAD请求(例如GET但没有有效负载)。 见https://ochronus.com/http-head-request-good-uses/

它不需要预检检查,混淆是因为规范的旧版本,请参阅 Why does a cross-origin HEAD request need a preflight check?

所以你可以使用上面的答案,使用jQuery库(没有说出来)但是用

type: 'HEAD'

---&GT;

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          type: 'HEAD',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>

当然,你也可以使用香草js或道场或其他......

答案 11 :(得分:0)

let webSite = 'https://google.com/' 
https.get(webSite, function (res) {
    // If you get here, you have a response.
    // If you want, you can check the status code here to verify that it's `200` or some other `2xx`.
    console.log(webSite + ' ' + res.statusCode)
}).on('error', function(e) {
    // Here, an error occurred.  Check `e` for the error.
    console.log(e.code)
});;

如果您使用节点运行此操作,只要Google未关闭,它就会控制日志200。

答案 12 :(得分:0)

我不知道你正在运行什么版本的Ruby,但你是否尝试过为ruby而不是javascript实现ping? http://raa.ruby-lang.org/project/net-ping/

答案 13 :(得分:-4)

您可以使用以下命令从javaScript运行DOS ping.exe命令:

function ping(ip)
{
    var input = "";
    var WshShell = new ActiveXObject("WScript.Shell");
    var oExec = WshShell.Exec("c:/windows/system32/ping.exe " + ip);

    while (!oExec.StdOut.AtEndOfStream)
    {
            input += oExec.StdOut.ReadLine() + "<br />";
    }
    return input;
}

这是被要求的,还是我错过了什么?

答案 14 :(得分:-6)

只需替换

file_get_contents

$ip = $_SERVER['xxx.xxx.xxx.xxx'];
exec("ping -n 4 $ip 2>&1", $output, $retval);
if ($retval != 0) { 
  echo "no!"; 
} 
else{ 
  echo "yes!"; 
}

答案 15 :(得分:-8)

它可能比所有这些容易得多。如果你想加载你的页面然后检查一些外国页面的可用性或内容以触发其他网页活动,你可以使用这样的javascript和php。

yourpage.php

<?php
if (isset($_GET['urlget'])){
  if ($_GET['urlget']!=''){
    $foreignpage= file_get_contents('http://www.foreignpage.html');
    // you could also use curl for more fancy internet queries or if http wrappers aren't active in your php.ini
    // parse $foreignpage for data that indicates your page should proceed
    echo $foreignpage; // or a portion of it as you parsed
    exit();  // this is very important  otherwise you'll get the contents of your own page returned back to you on each call
  }
}
?>

<html>
  mypage html content
  ...

<script>
var stopmelater= setInterval("getforeignurl('?urlget=doesntmatter')", 2000);

function getforeignurl(url){
  var handle= browserspec();
  handle.open('GET', url, false);
  handle.send();
  var returnedPageContents= handle.responseText;
  // parse page contents for what your looking and trigger javascript events accordingly.
  // use handle.open('GET', url, true) to allow javascript to continue executing. must provide a callback function to accept the page contents with handle.onreadystatechange()
}
function browserspec(){
  if (window.XMLHttpRequest){
    return new XMLHttpRequest();
  }else{
    return new ActiveXObject("Microsoft.XMLHTTP");
  }
}

</script>

应该这样做。

触发的javascript应该包含clearInterval(stopmelater)

让我知道这是否适合您

杰里

答案 16 :(得分:-13)

您可以尝试在您的网页中使用PHP ......如下所示:

<html><body>
<form method="post" name="pingform" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<h1>Host to ping:</h1>
<input type="text" name="tgt_host" value='<?php echo $_POST['tgt_host']; ?>'><br>
<input type="submit" name="submit" value="Submit" >
</form></body>
</html>
<?php

$tgt_host = $_POST['tgt_host'];
$output = shell_exec('ping -c 10 '. $tgt_host.');

echo "<html><body style=\"background-color:#0080c0\">
<script type=\"text/javascript\" language=\"javascript\">alert(\"Ping Results: " . $output . ".\");</script>
</body></html>";

?>

这未经过测试,因此可能有错字等...但我相信它会起作用。也可以改进......