`

Tools

阅读更多

.一、背景
假设有一个图片浏览的网页,每日pv量大概在80,000,000左右,uv量在3,000,000左右,现需要统计每张图片的pv量。
二、方案
方案1 每浏览一张图片,发送图片id和浏览数量到后台,并记录到数据库(可能会涉及到缓存机制,比如Memcache)
方案2 在页面中用js记录用户访问每张图片的次数,在用户关闭网页或刷新页面时,发送图片id和浏览数量到后台,并记录到数据库(可能会涉及到缓存机制,比如Memcache)
分析:
方案1中,需要发送大概80,000,000次(pv量)数据到后台,而方案2中只需要发送3,000,000次(uv量)数据,降低了1个数量级,这大大减轻了接入层机器的负载
三、实现
采用方案2。需要根据用户的关闭网页行为做js事件触发,此处我们用到onbeforeunload事件。

代码如下:

[javascript] view plaincopyprint?
  1. <script>  
  2. var g_img_pv = {};  //用于记录图片id和点击次数   
  3.   
  4. function Fempty(v){  
  5.     if(v!=null && (typeof(v)=='object' || typeof(v)=='function')) return false;  
  6.     return ((""==v || undefined==v || null==v)?true:false);  
  7. }  
  8. function FaddEvent(e,evt,fn,isID)  
  9. {  
  10.     if(isID==true) e=Fid(e);  
  11.     if(!Fempty(e.attachEvent) && (typeof(e.attachEvent)=="function" || typeof(e.attachEvent)=="object"))  
  12.         e.attachEvent("on"+evt,fn);  
  13.     else if(!Fempty(e.addEventListener) && (typeof(e.addEventListener)=="function" || typeof(e.addEventListener)=="object"))  
  14.         e.addEventListener(evt,fn,false);  
  15. }  
  16. function stat_img_pv()  
  17. {  
  18.     if(!g_img_pv)  
  19.     {  
  20.         return;  
  21.     }  
  22.     var ids = '', counts = '';  
  23.     for(var picid in g_img_pv)  
  24.     {  
  25.         if(parseInt(picid) == picid)  
  26.         {  
  27.             ids += picid + ',';  
  28.             counts += g_img_pv[picid] + ',';  
  29.         }  
  30.     }  
  31.     ids = ids.substring(0, ids.length-1);  
  32.     counts = counts.substring(0, counts.length-1);  
  33.   
  34.     var url = 'http://www.example.com/statimgpv.php?'+ids+'&counts='+counts+'&t='+Math.random();  
  35.     var img = new Image();  
  36.     img.src = url;  
  37.     setTimeout(function(){},1000);  
  38. }  
  39. FaddEvent(window, 'beforeunload', stat_img_pv, false);  
  40. </script>  
<script>
var g_img_pv = {};	//用于记录图片id和点击次数

function Fempty(v){
	if(v!=null && (typeof(v)=='object' || typeof(v)=='function')) return false;
	return ((""==v || undefined==v || null==v)?true:false);
}
function FaddEvent(e,evt,fn,isID)
{
	if(isID==true) e=Fid(e);
	if(!Fempty(e.attachEvent) && (typeof(e.attachEvent)=="function" || typeof(e.attachEvent)=="object"))
		e.attachEvent("on"+evt,fn);
	else if(!Fempty(e.addEventListener) && (typeof(e.addEventListener)=="function" || typeof(e.addEventListener)=="object"))
		e.addEventListener(evt,fn,false);
}
function stat_img_pv()
{
	if(!g_img_pv)
	{
		return;
	}
	var ids = '', counts = '';
	for(var picid in g_img_pv)
	{
		if(parseInt(picid) == picid)
		{
			ids += picid + ',';
			counts += g_img_pv[picid] + ',';
		}
	}
	ids = ids.substring(0, ids.length-1);
	counts = counts.substring(0, counts.length-1);

	var url = 'http://www.example.com/statimgpv.php?'+ids+'&counts='+counts+'&t='+Math.random();
	var img = new Image();
	img.src = url;
	setTimeout(function(){},1000);
}
FaddEvent(window, 'beforeunload', stat_img_pv, false);
</script>



写到这里好像是完成了,运行一下试试,用httpwatch抓一下包看看http请求是否成功。悲剧,在ie和firefox下,http请求被aborted了,截图如下:



这是怎么回事呢?个人认为,在设置完img变量的src属性后,并没有立即触发http请求,这样,当onbeforeunload响应完成,然后是响应onunload,接着页面就关闭了,这就导致了我们的img.src还没有被触发。
怎么办呢?第一个反应是在设置完img变量的src属性后,sleep一会,从而等待http请求被触发。但是js里貌似没有sleep函数,怎么办?
一种笨方法:
在img.src = url;后,加一个长时间的操作,比如加一个for循环,这样不就达到了延迟的目的了吗?试一下,firefox下ok,ie下,不好使…… 万恶的ie啊!

下面给出一种解决办法(在ie和firefox下测试均ok):

 

 

[javascript] view plaincopyprint?
  1. function stat_img_pv()  
  2. {  
  3.     ……  
  4.     var img = new Image();  
  5.     img.src = url;  
  6.     setTimeout(function(){},1000);  //就是加入这一行!   
  7. }  
function stat_img_pv()
{
	……
	var img = new Image();
	img.src = url;
	setTimeout(function(){},1000);	//就是加入这一行!
}



但是为啥好使我就不知道了,很偶然的尝试下发现ok。等待大牛的解答!



onbeforeunload与onunload事件
onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来指定或者在<body>里指定。区别在于onbeforeunload在onunload之前执行,它还可以阻止onunload的执行。
onbeforeunload也是在页面刷新或关闭时调用,onbeforeunload是正要去服务器读取新的页面时调用,此时还没开始读取;而onunload则已经从服务器上读到了需要加载的新的页面,在即将替换掉当前页面时调用。onunload是无法阻止页面的更新和关闭的。而onbeforeunload可以做到。
1、onbeforeunload事件:
说明:目前三大主流浏览器中firefox和IE都支持onbeforeunload事件,opera尚未支持。
用法:
·object.onbeforeunload = handler
·<element onbeforeunload = "handler" … ></element>
描述:
事件触发的时候弹出一个有确定和取消的对话框,确定则离开页面,取消则继续待在本页。handler可以设一个返回值作为该对话框的显示文本。
  触发于:
  ·关闭浏览器窗口
  ·通过地址栏或收藏夹前往其他页面的时候
  ·点击返回,前进,刷新,主页其中一个的时候
  ·点击 一个前往其他页面的url连接的时候
  ·调用以下任意一个事件的时候:click,document write,document open,document close,window close ,window navigate ,window NavigateAndFind,location replace,location reload,form submit.
  ·当用window open打开一个页面,并把本页的window的名字传给要打开的页面的时候。
  ·重新赋予location.href的值的时候。
  ·通过input type=”submit”按钮提交一个具有指定action的表单的时候。
  可以用在以下元素:
  ·BODY, FRAMESET, window
  平台支持:
  IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, Firefox0.9+
示例:

[javascript] view plaincopyprint?
  1. <html xmlns="http://www.w3.org/1999/xhtml">  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  
  4. <title>onbeforeunload测试</title>  
  5. <script>  
  6. function checkLeave(){  
  7.       event.returnValue="确定离开当前页面吗?";  
  8. }  
  9. </script>  
  10. </head>  
  11. <body onbeforeunload="checkLeave()">  
  12. </body>  
  13. </html>  
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>onbeforeunload测试</title>
<script>
function checkLeave(){
      event.returnValue="确定离开当前页面吗?";
}
</script>
</head>
<body onbeforeunload="checkLeave()">
</body>
</html>



但是onbeforeunload有个小毛病,就是页面刷新时,他还是会调用到onbeforeunload,为什么?其实刷新就相当于关闭了这个IE再重新打开的意思,因此还是会调用到onbeforeunload。
究竟怎么解决刷新不调用onbeforeunload呢?网上提供很多方法,本人觉得最实用还是以下这段JS

 

 

[javascript] view plaincopyprint?
  1. window.onbeforeunload = function(){     
  2.       var n = window.event.screenX - window.screenLeft;     
  3.       var b = n > document.documentElement.scrollWidth-20;     
  4.       if(b && window.event.clientY<0 || window.event.altKey)     
  5.       {     
  6.           alert("是关闭而非刷新");     
  7.           window.event.returnValue = "是否关闭?";  
  8.       }else{  
  9.           alert("是刷新而非关闭");     
  10.       }     
  11. }  
window.onbeforeunload = function(){   
      var n = window.event.screenX - window.screenLeft;   
      var b = n > document.documentElement.scrollWidth-20;   
      if(b && window.event.clientY<0 || window.event.altKey)   
      {   
          alert("是关闭而非刷新");   
          window.event.returnValue = "是否关闭?";
      }else{
          alert("是刷新而非关闭");   
      }   
}



2、onunload事件
用法:
·object.onunload = handler
·<element onunload = "handler"></element>
描述:
当用户关闭一个页面时触发 onunload 事件。
  触发于:
  ·关闭浏览器窗口
  ·通过地址栏或收藏夹前往其他页面的时候
  ·点击返回,前进,刷新,主页其中一个的时候
  ·点击一个前往其他页面的url连接的时候
  ·调用以下任意一个事件的时候:click,document write,document open,document close,window close ,window navigate ,window NavigateAndFind,location replace,location reload,form submit.
  ·当用window open打开一个页面,并把本页的window的名字传给要打开的页面的时候。
  ·重新赋予location.href的值的时候。
  ·通过input type=”submit”按钮提交一个具有指定action的表单的时候。
示例:

 

 

[javascript] view plaincopyprint?
  1. <html xmlns="http://www.w3.org/1999/xhtml">  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  
  4. <title>onunload测试</title>  
  5. <script>  
  6.   function checkLeave(){  
  7.     alert("欢迎下次再来!");  
  8.   }  
  9. </script>  
  10. </head>  
  11. <body onunload="checkLeave()">  
  12. </body>  
  13. </html>  
  • UE.rar (9.9 MB)
  • 下载次数: 1
分享到:
评论

相关推荐

    Geotools Java API 开发gis的参考资料

    org.geotools org.geotools.arcsde org.geotools.arcsde.data org.geotools.arcsde.data.versioning org.geotools.arcsde.data.view org.geotools.arcsde.filter org.geotools.arcsde.gce org.geotools....

    Adbtools新版Adbtools新版

    Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools新版Adbtools...

    VMware tools 11.1.1.rar

    VMware Tools 11.1.1支持以下来宾操作系统: windows.iso supports Windows 7 SP1 or Windows Server 2008 R2 SP1. VMware Tools 11.1.1依赖并附带用于Visual Studio 2015、2017和2019的Microsoft Visual C ++ ...

    velocity-tools-generic-3.1-API文档-中英对照版.zip

    赠送jar包:velocity-tools-generic-3.1.jar; 赠送原API文档:velocity-tools-generic-3.1-javadoc.jar; 赠送源代码:velocity-tools-generic-3.1-sources.jar; 赠送Maven依赖信息文件:velocity-tools-generic-...

    pdf24 tools(PDF24工具箱)官方中文版V10.7.1 | pdf24tools下载

    ​pdf24 tools是由德国Geek Software公司开发的一款优秀实用且完全免费的PDF工具箱软件,PDF24工具箱包含PDF分割/合并、PDF压缩、PDF编辑器、PDF加密/解密、PDF页面/图像提取、PDF比较、PDF转换、添加PDF水印等多种...

    VMware tools 10.3.10.rar

    VMware Tools 10.3.10发行版冻结了对Solaris guest虚拟机的支持。 现在可以通过Microsoft的Windows Server 2016和Windows Server 2019的Windows Update服务获得pvscsi驱动程序。当驱动程序发布过程完成时,将通过...

    CPNTools建模工具

    仿真工具cPN Tools是一款优秀的Petri网仿真工具,是仿真和分析着色petri网建立的模型。CPNTools不仅支持基础着色Petri网建立模型,也支持带有时间和分层的着色petri网建立模型。CPNTools支持CPN ML编程语言,颜色集...

    platform-tools and build-tools for aarch64 34.0.3

    platform-tools and build-tools for arm aarch64 34.0.3 build-tools/aapt build-tools/aapt2 build-tools/aidl build-tools/dexdump build-tools/split-select build-tools/zipalign platform-tools/adb platform-...

    Daemon Tools v4.03 V4.03HE 汉化版

    Daemon Tools v4.03 V4.03HE 汉化版,相信经常使用虚拟光驱的人都应该记得,这是当年极其经典的一个版本。 现在的虚拟光驱越做越大,功能也越来越多,最新的版本Daemon Tools 安装后要占用硬盘50多M,然尔对一般的...

    虚拟光驱 daemon_tools_347cn_eric

    虚拟光驱 daemon_tools_347cn_eric虚拟光驱 daemon_tools_347cn_eric虚拟光驱 daemon_tools_347cn_eric虚拟光驱 daemon_tools_347cn_eric虚拟光驱 daemon_tools_347cn_eric虚拟光驱 daemon_tools_347cn_eric虚拟光驱...

    Mac版本cmdline-tools工具包

    解压缩,新建目录并放到目录:~/Library/Android/sdk/cmdline-tools/latest。cd到目录执行`./sdkmanager "build-tools;32.0.0" "platforms;android-32" "platform-tools"`, #加~/.bash_profile ANDROID_HOME="/...

    platform-tools(安卓调试工具包).zip

    platform-tools_r31.0.3-windows.zip platform-tools是很多刷机的朋友都会用到的工具包,Android SDK其中的platform-tools包可以对安卓设备进行调试,包括解锁、刷机等操作都可以使用这个工具包来进行,其中包含开发...

    geotools稳定版本geotools-19.4-bin.zip

    import org.geotools.data.FileDataStore; import org.geotools.data.FileDataStoreFinder; import org.geotools.data.simple.SimpleFeatureSource; import org.geotools.map.FeatureLayer; import org.geotools.map...

    VMwareTools-9.6.2-1688356.tar.gz

    VMware tools 9.6.2 是vmware player 6.0.2 (VMware@Player 6.0.2 build - 1744117) 所带的tools,安装之后可以实现与Windows共享目录被ubuntu访问,实现资源共享,vmware player全屏等 使用方法: - 拷贝至Linux...

    Android platform-tools

    platform-tools是一款安卓调试工具包。platform-tools里面包括了adb、fastboot、etc1tool等常用调试工具,你可以利用它们将安卓系统在其他设备上调试或者刷机、解锁等操作,十分实用。 platform-tools功能介绍: ...

    tools_r23.0.1-windows.zip

    终于可以发100M+的文档了 Xamarin for VS中 如果你的Xamarin版本比较低 则需要同样低版本的SDK tools与之相配 否则看不到layout图 我贡献一批吧 都是自己战斗过 被虐过的地方 错误码: Disconnected from layout ...

    platform-tools_r22-windows.zip

    1,配置adb环境变量Android和path (如:变量名:Android 变量值:E:\Android\sdk\platform-tools;E:\Android\sdk\tools; 变量名:path 变量值: E:\Android\sdk\platform-tools;E:\Android\sdk\tools;) 2,在...

    Android Sdk Platform-tools 28最新版本

    Although some new features in these tools are available only for recent versions of Android, the tools are backward compatible, so you need only one version of the SDK Platform-Tools 28 版本

    DAEMON Tools Pro 4.41.0314.0232真正完美破解版 32bit&64bit;

    1、鼠标右键,以管理员身份运行包里的setup.exe,安装Daemon Tools Pro,选择Advanced Edition,使用许可选择trial license 2、如果安装程序要求重启电脑,重启电脑;重启后, Ctrl+Shift+Esc运行任务管理器,杀...

Global site tag (gtag.js) - Google Analytics