我正在开发特定的移动线框网页,其中在为用户启动计时器加载网络内容主体之后,在此期间用户即将回答问题。有两种情况可以回答这个问题。 1.用户无法及时回答,服务器会将回答视为失败。 2.用户在问题时间到期之前回答。
我需要阻止用户重新运行脚本以计算剩余秒数。我拒绝解决问题,在页面加载前端后可以与数据库进行通信,不,只有在问答之前和之后才允许我与数据库通信,因为我想避免在回答过程中丢失连接的问题。因此,我有时序的JS脚本如下:
iterator= 0;
secondsMax = 15;
elem = document.getElementById("secLeft");
elem.innerHTML = secondsMax ;
function timer() {
setTimeout(function(){
iterator++;
elem.innerHTML = secondsMax - iterator;
if(iterator == secondsMax ) {
// progress bar move... 1 question from 5
move();
iterator= 0;
//give signal to evaluate question ...
return;
}
timer();
}, 1000);
}
类似StackOverflow这样的问题只包含使用ajax的答案,因为它没有给服务器提供响应以重新加载页面。但我需要以编程方式阻止用户在前端刷新以防止作弊(但也许ajax是一个很好的解决方案,但我可能不理解它在这种情况下的用法)。你有什么想法,或解决方法怎么做?我对任何批评都持开放态度,好吧,如果这个解决方案非常糟糕(我是网络技术的新手),请自由地告诉我更好的方法。
提前感谢您的时间。
答案 0 :(得分:1)
首先,您必须进行服务器端验证以排除作弊方案。
例如,任何问题都有唯一的哈希与开始时间链接,当您收到与该哈希相关的答案时,您可以比较花费的时间......
在客户端,您可以在localstorage
中存储该问题的开始时间,如果页面加载找到当前问题哈希的localstorage条目 - 使用找到的起始值初始化计时器。
const TIME_ALLOWED = 10e3; // 10 sec
const QUESTION_HASH = '1fc3a9903';
// start = localStorage.getItem(QUESTION_HASH) else
let start = Date.now();
let timeleft = document.getElementById('timeleft');
let timer = setInterval(() => {
let timepass = Date.now() - start;
if (timepass >= TIME_ALLOWED) {
clearInterval(timer);
timeleft.innerText = 'Time is over';
// localStorage.setItem(QUESTION_HASH, null)
return;
}
let secs = (TIME_ALLOWED-timepass) / 1000 | 0;
let mins = secs / 60 | 0;
secs = secs % 60;
if (secs < 10) secs = '0' + secs;
timeleft.innerText = `${mins}:${secs}`;
}, 500);
const answer = e => {
if (Date.now() - start >= TIME_ALLOWED) return; // disallow to answer
clearInterval(timer);
timeleft.innerText = 'Answer received';
// localStorage.setItem(QUESTION_HASH, null)
}
Time left: <span id="timeleft"></span><br/>
<button onclick="answer()">Answer</button>