有没有可能通过 Javascript 来 ping 服务器?

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

我决定走用户端的 ping 路线。这样,我可以加载页面,只是让他们等待“服务器在线”的数据,而浏览我的内容。

如果任何人有上述问题的答案,或者他们知道一个解决方案,以保持我的页面加载速度,我肯定会感激它。

333969 次浏览

您不能在浏览器 Javascript 中进行常规 ping 操作,但是您可以通过从远程服务器加载图像来确定远程服务器是否处于活动状态。如果加载失败-> 服务器关闭。

您甚至可以使用 onload-event 计算加载时间。

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

  • 阿贾克斯
  • 使用带有 是可以联系到的的 java applet
  • 编写一个 ping 的 serverside 脚本,并使用 AJAX 与 serversidescript 通信
  • 您还可以在 flash 中 ping (actionscript)

我不知道你运行的是哪个版本的 Ruby,但是你有没有试过用 Ruby 代替 javascript 来实现 ping 呢?http://raa.ruby-lang.org/project/net-ping/

你可以试试这个:

Html放在服务器上,不管有没有任何内容,在 javascript 上做如下操作:

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

你可以尝试在你的网页中使用 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>";


?>

这是没有测试,所以它可能有打字错误等... 但我相信它会工作。可以改进太..。

为了保持请求快速,请缓存 ping 的服务器端结果,并每隔几分钟更新 ping 文件或数据库(或者不管您希望它是多么精确)。您可以使用 cron 运行 shell 命令,并将输出写入一个文件,webserver 将把这个文件包含到您的视图中。

标准 ping 的问题在于它们是 ICMP,也就是 很多地方出于安全和交通原因不让通行,这可能解释了失败的原因。

Ruby 在1.9之前有一个基于 TCP 的 ping.rb,它将在 Ruby 1.9 + 中运行。您所要做的就是将它从1.8.7版本的安装中复制到其他地方。我刚刚确认了它可以通过定位我家的路由器运行。

可能比那容易多了。如果你想加载你的页面,然后检查可用性或一些外国网页的内容,以触发其他网页的活动,你可以这样做,只使用 javascript 和 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)

如果可以的话告诉我

杰瑞

只是替换

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!";
}

我发现有人非常巧妙地使用了本机 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错误。如果有人可以验证一个替代的解决方案,我将把它作为接受的答案。

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
}


}

推出一个网络插座解决方案。

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);
}

更新: 此解决方案不再适用于主流浏览器,因为即使主机是一个不存在的 IP 地址,也会执行 onerror回调。

可以使用以下方法从 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;
}

这是他们要求的,还是我遗漏了什么?

如果您试图查看的是服务器是否“存在”,您可以使用以下方法:

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);

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

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

它不需要飞行前检查,混乱是因为旧版本的规范,见 为什么跨原点的 HEAD 请求需要飞行前检查?

因此,您可以使用上面的答案,即使用 jQuery 库(没有说出来) ,但是使用

type: 'HEAD'

--->

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

当然你也可以用香草 J 或者道场或者其他什么的。

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)
});;

如果你运行这与节点它将控制台日志200只要谷歌是不关闭。

const ping = (url, timeout = 6000) => {
return new Promise((resolve, 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(() => resolve(true))
.catch(() => resolve(false));
setTimeout(() => {
resolve(false);
}, timeout);
} catch (e) {
reject(e);
}
});
};

使用方法如下:

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