基本上,一旦用户在我的应用程序中留下网页,我需要使用AJAX调用PHP脚本,这将在网页上花费一些时间到数据库,然后离开页面。
等待AJAX请求完成非常重要,因为用户无法访问我的应用程序中的网页,除非他们在上一页上花了一定时间(比方说两分钟)。
这是我的jquery代码:
$(document).ready(function() {
var teid = TEID;
var startTime = new Date().getTime();
$(window).unload(function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
$.ajax({
type: 'POST',
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
});
});
如何更改它以便在离开网页之前等待AJAX请求结束?
编辑:
或者更好(更容易)让AJAX请求每分钟重复一次。这可能吗?
答案 0 :(得分:31)
好吧,您可以在AJAX调用上设置async: false
以使浏览器在执行任何其他操作之前等待请求完成,但请注意,这将在请求期间“挂起”浏览器。 / p>
$.ajax({
type: 'POST',
async: false,
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
从手册:
默认情况下,所有请求都是异步发送的(默认情况下设置为true)。如果需要同步请求,请将此选项设置为false。跨域请求和dataType:“jsonp”请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,并在请求处于活动状态时禁用任何操作。
答案 1 :(得分:7)
最佳解决方案是使用navigator.sendBeacon。它是全新的功能,开始在新版本的浏览器中实现。该功能适用于比Chrome 39和Firefox 31更新的浏览器。在撰写本文时,Internet Explorer和Safari不支持此功能。要确保您的请求在不支持新功能的浏览器中发送,您可以使用此解决方案:
var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
var client = new XMLHttpRequest();
client.open("POST", url, false); // third parameter indicates sync xhr
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(data);
};
希望这有帮助!
答案 2 :(得分:6)
如何在卸载处理程序中设置cookie?服务器应该在后续请求中看到它。
<script>
$(window).unload(function(){document.cookie='left_on='+(new Date())})
</script>
答案 3 :(得分:4)
对我来说,你的浏览器在关闭之前等待并不是一个好主意...
因为如果我真的要关闭它会怎么样?...
如果页面打扰了用户,那就不好了......
我的建议是,在页面中,你等待2分钟(如果需要2分钟),然后发送一个用户已完成2分钟的ajax ...
然后你可以在服务器端检查它是否有2分钟......
答案 4 :(得分:2)
尝试劫持用户的浏览器是一个坏主意,因为它会给他们带来不好的感觉并将其发送出去。
如果由于某种原因你想要在用户花费最少时间之前不要生成新页面,那么最好的办法是引导服务器端,即重定向到当前页面,直到请求的时间为止过去了。
您甚至不需要进行ajax调用,只需在会话中存储服务页面的时间戳,并且在经过一定时间后才显示以下页面。
请务必告诉用户他们必须等待新页面准备好,可能需要简单的javascript倒计时。
如果您希望用户实际将页面激活一段时间(即不要切换到另一个标签/窗口等待两分钟的时间),那么,我无法提出有效的解决方案。
答案 5 :(得分:1)
使用onbeforeunload
:
$(document).ready(function(){
window.onbeforeunload = function(){
// $.ajax stuff here
return false;
}
});
这至少会给用户一个messagebox
,询问他是否要关闭当前窗口/标签。
答案 6 :(得分:1)
我认为按照你的建议使用轮询技术要好得多,尽管它会对网络服务器造成一些负担。
$(document).ready(function() {
var teid = TEID;
var startTime = new Date().getTime();
var ajaxFunc = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
$.ajax({
type: 'POST',
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
};
setInterval(ajaxFunc, 60000);
})
当你可以使用websockets时,你会很高兴:)
答案 7 :(得分:0)
jQuery.ajax()
方法有async
选项。如果将其设置为false
,则呼叫将阻止,直到响应返回(或超时)。我非常害羞,调用它,会让浏览器在卸载处理程序中消失。
旁注:你不能依靠这个来工作。如果浏览器为用户提供取消卸载处理程序的选项(某些浏览器在等待一段时间后会执行此操作),则“站点上的时间花费”将永远不会更新。您可以向站点添加计时器,该计时器会定期调用服务器上的脚本并更新时间。您将没有准确的值,但在您的情况下,这不是必需的。
如果您只需要知道用户是否在页面上是X秒您可以在onload处理程序中设置超时(使用setTimeout(function, ms)
),如果用户花费了所需的时间,则会发出呼叫。所以不需要卸载处理程序。