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; }

解决办法是 注释它的执行部分,不使用它,虽说在执行静态化上用得着,但是这个方法威力太大,个人驾驭不了,只好关闭它,这样网站就不会被搞的到处都是随意上传的文件了。