1、关于B/S下的时间同步
之前接到一个小活,来处理javascript异步情况下,保持计时器校准的功能。原代码如下:
var T,S,KT,KS; function gameKanJiangDataC(diffTime, actionNo){ var $dom=$('#pre-kanjiang'); var thisNo=$('.kj-title span').html(); var tips='本期['+thisNo+']已截至投注'; if(diffTime<=0){ if($('#kaijiang .feipan')) $('#kaijiang .feipan em').html("X"); $dom.text('00:00:00'); $('#kaijiang .wjtips').html('正在封单中'); $('#btnPostBet').unbind('click'); $('#btnPostBet').bind('click', function(){ winjinAlert(tips,"alert"); }); var tipString='第 '+thisNo+' 期投注已截止!
清空预投注内容请点击"确定",不刷新页面请点击"取消"。'; var wjDialog=$('#wanjinDialog').html(tipString).dialog({ title:'温馨提示', resizable: false, width:450, minHeight:220, modal: true, buttons: { "确定": function() { $( this ).dialog( "close" ); gameActionRemoveCode(); }, "取消": function() { $( this ).dialog( "close" ); } } });//dialog end S=false; KS=true; if(KT) clearTimeout(KT); $('.kj-bottom span.last_issues').text($('.kj-title span').text()); setKJWaiting(kjTime); }else{ if(actionNo) $dom.prev().find('span').html(actionNo); var m=Math.floor(diffTime % 60), s=(diffTime---m)/60, h=0; if(s<10){ s="0"+s; } if(m<10){ m="0"+m; } if(s>60){ h=Math.floor(s/60); s=s-h*60; $dom.text((h<10?"0"+h:h)+":"+(s<10?"0"+s:s)+":"+m); }else{ h=0; $dom.text("00:"+s+":"+m); } if(S && h==0 && m==6 && s==0){ playVoice('/skin/sound/stop-time.wav', 'stop-time-voice'); } if(h==0 && m==0 && s==0){ loadKjData(); }else{ if($.browser.msie){ T=setTimeout(function(){ gameKanJiangDataC(diffTime); }, 1000); }else{ T=setTimeout(gameKanJiangDataC, 1000, diffTime); } } } }
修改后代码为
var T,S,KT,KS; # 修改处 # ####################################################################################### var startTime = new Date().getTime(); var count = 0; ####################################################################################### # 修改处 # function gameKanJiangDataC(diffTime, actionNo){ // console.log(diffTime); //console.log(actionNo); var $dom=$('#pre-kanjiang'); var thisNo=$('.kj-title span').html(); var tips='本期['+thisNo+']已截至投注'; if(diffTime<=0){ if($('#kaijiang .feipan')) $('#kaijiang .feipan em').html("X"); $dom.text('00:00:00'); $('#kaijiang .wjtips').html('正在封单中'); $('#btnPostBet').unbind('click'); $('#btnPostBet').bind('click', function(){ winjinAlert(tips,"alert"); }); var tipString='第 '+thisNo+' 期投注已截止!
清空预投注内容请点击"确定",不刷新页面请点击"取消"。'; var wjDialog=$('#wanjinDialog').html(tipString).dialog({ title:'温馨提示', resizable: false, width:450, minHeight:220, modal: true, buttons: { "确定": function() { $( this ).dialog( "close" ); gameActionRemoveCode(); }, "取消": function() { $( this ).dialog( "close" ); } } });//dialog end S=false; KS=true; if(KT) clearTimeout(KT); $('.kj-bottom span.last_issues').text($('.kj-title span').text()); setKJWaiting(kjTime); }else{ if(actionNo) $dom.prev().find('span').html(actionNo); var m=Math.floor(diffTime % 60), s=(diffTime---m)/60, h=0; if(s<10){ s="0"+s; } if(m<10){ m="0"+m; } if(s>60){ h=Math.floor(s/60); s=s-h*60; $dom.text((h<10?"0"+h:h)+":"+(s<10?"0"+s:s)+":"+m); }else{ h=0; $dom.text("00:"+s+":"+m); } if(S && h==0 && m==6 && s==0){ playVoice('/skin/sound/stop-time.wav', 'stop-time-voice'); } if(h==0 && m==0 && s==0){ loadKjData(); }else{ if($.browser.msie){ console.log($.browser.version) T=setTimeout(function(){ gameKanJiangDataC(diffTime-25); }, 1000); }else{ # 修改处 # ################################################################################## count++; var offset = new Date().getTime() - (startTime + count*1000); // console.log(offset); if(offset > 0){ var diffTime = (diffTime*1000 - Math.abs(offset))/1000; var devel = Math.floor(Math.abs(offset)/1000); T=setTimeout(gameKanJiangDataC, devel, Math.floor(diffTime)); }else{ var diffTime = (diffTime*1000 +Math.abs(offset))/1000; T=setTimeout(gameKanJiangDataC, 1000, Math.floor(diffTime)); } ################################################################################### # 修改处 # } } } }
我的思路是:
在异步开始前,获取初始时间,每次在执行到
count++;
时;
时间差 = 使用当时时间 - 初始时间 - 时间的累加。
时间差 >0 表示执行脚本变慢了,要加快执行
时间差 <0 表示执行脚本变快了,这个很少出现,所以默认执行就可以了。
结果:
每90分钟,时间差值为达到3~4分钟,这个很尴尬了。
后来问同事,证明在B/S下很难做到时高精度的时间准,即使使用ajax去后端拉取时间,且不说网络延时问题,setTimeout 和setInterval本就不是十分精确的函数,结论,尽量可能的与后台定时同步来保证时间的准确。
2、cms的上传漏洞
一直来phpcms频繁遭遇***,其中一个是其html.class.php文件中一个方法
/** * 写入文件 * @param $file 文件路径 * @param $copyjs 是否复制js,跨站调用评论时,需要该js */ private function createhtml($file, $copyjs = '') { $data = ob_get_contents(); ob_clean(); $dir = dirname($file); if(!is_dir($dir)) { mkdir($dir, 0777,1); } if ($copyjs && !file_exists($dir.'/js.html')) { @copy(PC_PATH.'modules/content/templates/js.html', $dir.'/js.html'); } $strlen = file_put_contents($file, $data); @chmod($file,0777); if(!is_writable($file)) { $file = str_replace(PHPCMS_PATH,'',$file); showmessage(L('file').':'.$file.'
'.L('not_writable')); } return $strlen; }
解决办法是 注释它的执行部分,不使用它,虽说在执行静态化上用得着,但是这个方法威力太大,个人驾驭不了,只好关闭它,这样网站就不会被搞的到处都是随意上传的文件了。