思路是有了,那我们得先把自己的思路给验证一下,验证呢,就是得把我们得想法从流程上走通了,用最简单的实现证明这个方案是可行的。
首先,操刀写段JavaScript,咱也来试试传说中的onbeforeunload,jQuery是我的最爱,自从用上了他就离不开了。OK,即使不用jQuery一个函数一行代码也能实现,但是不用就是不舒服。很简单,就先随便弹个框吧:
$(function(){ window.onbeforeunload=function(){ alert("Are you sure exit this page?"); } });
嗯,不错,一切正常,当试图关闭或者刷新网页时,准确无误的弹出了令人厌恶的对话框。
下一步,测试获取开始时间和网页关闭时的时间:
$(function(){ var start_time = new Date(); window.onbeforeunload=function(){ var leave_time = new Date(); alert("start at:"+start_time.toUTCString() +"\nleave at:"+leave_time.toUTCString() +"\nAre you sure exit this page?"); } });
嗯,还可以,正常的获取到了开始的时间和离开网页的时间。但如果你的人品爆发,你也许碰到了这样的一个问题,这个框怎么弹了两次啊,莫名其妙!这个原因在于Firefox或者IE当中,如果你当前查看的标签页是最后一个标签页,那么onbeforeunload会被调用两次。我们当然不希望其被调用两次了,如果调用两次,那么将给服务器发送两条记录,这个是浪费服务器资源的一件事情。那该怎么办呢?只好在程序中记录下是不是已经被关过一次了:
$(function(){ var start_time = new Date(); var onbeforeunload_called=false; window.onbeforeunload=function(){ if(onbeforeunload_called) return; onbeforeunload_called = true; var leave_time = new Date(); alert("start at:"+start_time.toUTCString() +"\nleave at:"+leave_time.toUTCString() +"\nAre you sure exit this page?"); } });
不错,问题解决!恶心的对话框终于不会出来两次了。
最后,我们还需要测试检查看是否能在onbeforeunload中给服务器发送信息。
$(function(){ var start_time = new Date(); var onbeforeunload_called=false; window.onbeforeunload=function(){ if(onbeforeunload_called) return; onbeforeunload_called = true; var leave_time = new Date(); $.post("try-javascript-server.php", {start_at:start_time.toUTCString(), leave_at:leave_time.toUTCString()}, function(data){alert(data);} ); alert("start at:"+start_time.toUTCString() +"\nleave at:"+leave_time.toUTCString() +"\nAre you sure exit this page?"); } });
我们的服务器代码:
exit(var_dump($_POST));
OK,搞定,完全正常。但是,测试到此并没有结束,我们需要把alert的测试代码去除,而真正的去在PHP代码中做log记录,然后,我们还需要测试我们不得不兼顾的IE系列尤其IE6浏览器,这样,我们的流程才算是真正的完全走通了。这里贴出在服务器端记录log的测试代码:
<?php $logfile = "/tmp/try-javascript.log"; $log = file_exists($logfile)? file_get_contents($logfile) : ""; file_put_contents($logfile, $log.json_encode($_POST)."\n");