前几天准备在这个博客上装一个Google Analytics插件,虽然我知道这里其实没有人访问的(人艰不拆)。然后我就非常好奇GA的原理,因为WebSocket才出来没多久,以前的异步信息到底是怎么传递的呢?按照我一贯的小猫钓鱼风格,我决定来一探究竟。
首先还是去找了Google Urchin的代码看,对Javascript的语法不太习惯,看得有点云里雾里。不过还是看出来一点端倪,就是Image。简单来说,在客户端JavaScript中new一个Image对象,然后指定它的src属性,可以引起浏览器对图片的动态加载。聪明的工程师们就是利用了这样一个特性(URL中包含的信息)最终实现的客户端信息的动态传递。听起来也是挺简单的,何不尝试做一个demo呢?
前面学过一点三脚猫水平的node.js,这里就选择用它了,毕竟几行代码就可以搞定。首先还是要做一个web页面,代码如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Advertise</title>
<script language = "JavaScript">
var count = 0;
function preloader()
{
var img = new Image();
img.src = "beautiful.jpg";
console.log("in preloader()");
}
function realtimeloader() {
var img1 = new Image();
img1.onload = printlog;
img1.src = "http://127.0.0.1:3001/"+"compass.jpg" + "?" + "count=" + count;
console.log("start loading image!")
showtime();
count += 1;
}
function printlog() {
console.log("finish loading image!")
showtime();
}
function showtime() {
var myDate = new Date();
var minutes = myDate.getMinutes(); //获取当前分钟数(0-59)
var seconds = myDate.getSeconds(); //获取当前秒数(0-59)
var millseconds = myDate.getMilliseconds(); //获取当前毫秒数(0-999)
console.log(minutes + "分" + seconds + "秒" + millseconds + "毫秒");
}
</script>
</head>
<body onLoad = "javascript:preloader()">
<h1>image cache</h1>
<h2>Imageshow<span id="latency"></span></h2>
<a href="#" onMouseOver="javascript:realtimeloader() ">
<img name="image" src = "ugly.jpg">
</body>
</html>
在页面的body中定义了一个超链接,当鼠标移动到这个超链接上时,就会触发执行realtimeloader()函数。在这个事件函数中,我们会新建一个Image并指定它的src,注意这里的count是为了避开浏览器缓存。没有count的话,浏览器就不会多次发送Get请求了。"http://127.0.0.1:3001/"是我们图片服务器的地址端口,相当于GA系统中的Google服务器。客户网站的服务器工作在3000端口,相当于嵌入GA代码的客户网站。服务器的代码如下(用express,简直不要太简单):
var express = require('express')
, http = require('http')
, path = require('path')
var app = express();
app.use(express.static('public'));
var server = http.createServer(app)
server.listen(3000);
然后就是图片服务器(虽然图片不是我们的重点,在GA系统中图片也只是一个傀儡)的代码,如下:
var express = require('express')
, http = require('http')
, path = require('path')
var app = express();
app.use(function (req, res, next) {
console.log(req.url);
next();
});
app.use("/",express.static('public'));
var server = http.createServer(app)
server.listen(3001);
在图片服务器这里,我们会把Get请求的URL打印出来,我们并没有对页面动态信息(count的值)进行进一步的分析和使用。然后就是测试和实验了。首先是访问服务器1(客户网站)的效果图:
然后是服务器2(图片服务器)的日志输出:
统计系统也是用这方法。