Skip to content

图像 Ping

对于 html 中的

html
<img src="http://www.baidu.com/xx/1.jpg" />

img.src 是可以不遵循同源策略只能访问当前域名下的静态资源,那么我们就可以借助于这个设计实现通过请求图片的方式来跨域发送请求。

但是我们需要知道的 img 元素的 src 只是一个 get 请求去服务器获取图片资源数据,没有什么请求成功后的回调的处理,只有 onload、onerror 的事件,但是也不能获取服务器端的返回数据。

所以 img 跨域请求的优缺点如下:

优点:
  • 简单,兼容性好,不需要服务器做针对性处理。
缺点:
  • 只能单向通信,即客户端发送信号给服务端,无法接收到服务端的回复
  • 只能发送 GET 请求
  • 容易被浏览器缓存请求,导致请求发送不出去。(解决方式,在 URL 上加入时间戳)

其实我们就想到 jsonp 的原理,也是借助 script 标签可以加载非同源的资源数据,但是他却可以执行回调功能,这个是为什么,具体可以看

JSONP

使用原则

在某些小巧的跨域请求的时候可以使用 Image.src,比如统计 A 链接被点击的几次、img 被点击了几次, 这些场景下发送给服务器的数据流很小(GET 请求,2k 左右)客户端也不关心服务器返回的结果(不能像 JSONP 成功后执行 callback),只关心请求是否请求成功

实现

    1. 如统计链接的点击次数
js
/**
* 客户端的设计
*/
function translateA(item){
    // create Img
    item = item!=null && item.tagName ? item : this;

    // 创建一个不显示的图片元素,其地址不是图片的地址,只是用img可以使用跨域的GET请求去与服务器通信
    var image = document.createElement("IMG");
    //设置图片的地址为统计数据发送的接口地址
    image.src = "http://www.baidu.com?
    vender=0&href="+encodeURIComponent(item.href)+"&text="+encodeURIComponent(item.innerHTML)+
    "&target="+encodeURIComponent(item.target)+"&style="+encodeURIComponent(item.style.cssText)+
    "&location="+encodeURIComponent(window.location.href) +"&referrer=" +
    encodeURIComponent(document.referrer) + "&t="+ new Date().getTime();

    //设置图片的宽高为0 让其不显示
    image.height = 0;
    image.width = 0;

    item.requestTimes = item.requestTimes ? item.requestTimes ++ : 0;
    //处理图片请求成功和失败的处理方法
    image.onerror = (error ) => {};
    image.onload = (success) => {};

    //插入到DOM树中就会请求数据
    document.body.appendChild(image);
    return true;
}

/**
* 服务器端的设计
*/

{
	//固定返回一个size很小的图片作为responese
	fs.createReadStream('../image/1.jpg').pipe(res);
}

问题

  1. 为什么使用 gif,而不是 png、jpg 等

使用的是 1*1 像素的透明 GIF ,最小的 BMP 文件需要 74 个字节,PNG 需要 67 个字节,而合法的 GIF,只需要 43 个字节。 同样的响应,GIF 可以比 BMP 节约 41%的流量,比 PNG 节约 35%的流量。