动态创建图像经常用于图像Ping。图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是像素图或204响应。通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,它能知道响应是什么时候接收到的。
图像Ping最常用于跟踪用户点页面或动态广告曝光次数。图像Ping有两个主要的缺点,一是只能发送GET请求,二是无法访问服务器的响应文本。因此,图像Ping只能用于浏览器与服务器间的单向通信。
我们每天浏览很多的网页,有时候可能会发现某些图片( <img> )是来自其他网站的,其实你看到的就是一种跨域,由于图片不受“ 同源策略 ”限制,我们就可以利用图片进行跨域了。我们将图片的 src 属性指向请求的地址,通过监听 load 和 error 事件,就能知道响应什么时候接受了,响应的数据可以是任意内容,但通常是像素图或204响应。
var btn = document.querySelector("#start-ping");
btn.onclick = function(){
var img = new Image();
img.onload = img.onerror = function(obj){
document.querySelector("#result").innerHTML = "finished";
};
img.src = "http://localhost:3000/img?r="+Math.random();
};
服务器端我们使用 express ,简单的代码如下:
router.get('/img', function(req, res, next) {
res.send('我是一张图片,我说这句话好像没什么用');
});
在来看个小例子,客户端点击链接时触发跨域请求:
<a href="javascript:void(0);" οnclick="Click()">点击我</a>
<script>
function Click(){
var img=new Image();
img.οnlοad=function(){
alert('DONE');
}
img.src="http://www.othersite.com/demo4.ashx?r="+Math.random();
}
</script>
服务端进行简单的计数,并且发送回一像素大小的图像。客户端接收到该结果后会弹窗提示“DONE”。
public static int Count=0;
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain" ;
Count++;
context.Response.ContentType = "image/gif" ;
System.Drawing. Bitmap image = new System.Drawing. Bitmap(1, 1);
image.Save(context.Response.OutputStream,System.Drawing.Imaging.
ImageFormat .Gif);
context.Response.Write(Count);
}