我在检查 XMLHttp 和随机浏览器线程的浏览器兼容性时遇到了这个问题。我想我会给出我想出的工作示例,因为我很快就需要类似的东西,并且认为这个问题可以用一个更大的示例来解决。
底部的代码非常少
请原谅我这有点混乱,这是一个原始的例子。
<?php
// Do not forget session start if copying into your own code..
if (isset($_GET['keepalive'])) {
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Content-Type: application/json');
$boolStatusOfSession = TRUE; // Something like: $boolStatusOfSession = (isset($_SESSION['MyTokenWhenSignedIn']) ? TRUE : FALSE);
echo json_encode(array('status'=>$boolStatusOfSession));
exit;
}
?>
<html>
<head></head>
<body>
<p>This script will throttle the mouse movement event to a rate of once per second max and perform a keep alive request to the same page along with a json response of the session status</p>
<p id="debugbox"><b>Server Keep Alive: </b>please wait for the timer (10 seconds)</p>
<p id="debugbox2"></p>
<script>
var elmDebug = document.getElementById('debugbox');
var elmDebug2 = document.getElementById('debugbox2');
var idleStart = Math.floor(Date.now() / 1000);
function keepAlivePoster() {
objHttp = new XMLHttpRequest();
objHttp.onreadystatechange = function() {
var strDebug = "<b>Server Keep Alive: </b> ";
if (objHttp.readyState == XMLHttpRequest.DONE) {
idleStart = Math.floor(Date.now() / 1000);
objResp = JSON.parse(objHttp.responseText);
if (objResp.hasOwnProperty('status') && objResp.status == true) {
// DO STUFF HERE WHEN SIGNED IN (Or do nothing at all)
strDebug += "Signed In, ";
} else {
// DO STUFF HERE WHEN SIGNED OUT (A window reload if your page can handle the session change)
strDebug += "Signed Out, "; // Or does not exist / error.. best to use a int status
}
}
elmDebug.innerHTML = strDebug + "Updated at " + Math.floor(Date.now() / 1000);
elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
}
objHttp.open('GET', '?keepalive');
objHttp.send(null);
};
function throttleController (callback, limit) { // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
var wait = false; // Initially, we're not waiting
elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
return function () { // We return a throttled function
if (!wait) { // If we're not waiting
callback.call(); // Execute users function
wait = true; // Prevent future invocations
setTimeout(function () {wait = false;}, limit); // After a period of time, allow future invocations again
}
}
}
window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000)); // Allow "idleCallback" to run at most 1 time every 10 seconds
</script>
</body>
</html>
当然,您可以删除一些代码(调试等,因此是一个简单的基本脚本示例)
最小代码
function keepAlivePoster() {
objHttp = new XMLHttpRequest();
objHttp.open('GET', '?keepalive');
objHttp.send(null);
};
function throttleController (callback, limit) { // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
var wait = false; return function () {
if (!wait) { callback.call(); wait = true; setTimeout(function () {wait = false;}, limit); }
}
}
window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000));
最后一行您要复制的任何其他事件,当您使用多个事件时,您还希望在更高的范围/全局上设置等待变量。
为什么php状态/代码
那么首先这将在另一个文件中,该文件在 html 生成之前就包含在内。但理想情况下,您希望 GET 请求尽可能小,并带有一些规则等等。所以我禁用了该功能要缓存的页面和 json 响应可以很容易地被浏览器使用,同时提供一个简单的检查来重定向/重新加载(如果需要)。