一个通用广告脚本数据加载的容错
最基本的需求
写一个通用的广告脚本文件,传递不同的广告ID,加载对应的数据出来,上报数据,最后显示出来
最简单的做法
每个站点,直接请求广告地址,带上不同参数,例如这样:
var script = document.createElement("script");
script.src = 'ad.com?id=id1&callback=cb';
document.body.appendChild(script);
function cb(param){
//do something
new Image().src = "report.com?id=id1";
}
以上做法存在的问题:
- 每个站点都需要记住请求的地址,万一地址改了,全都要改
- 每个站点,都需要自己去写请求,以及回调
- 每个站点,都需要自己去上报数据
- 请求失败了,怎么办?
- 请求时间很长,怎么办?
站点的使用,更应该关心的是:
- 统一的接口
- 只需要传ID和回调函数
- 返回需要的数据进行渲染页面
- 错误、失败、上报、超时等不需要关心
我们可以这样做
1、统一处理请求
采用类
jQuery
的方式来进行jsonp
请求,增加超时和错误监控
//简易版jsonp
;var __GetScript = function(){
//发送请求(闭包)
//param object json参数
//param.url 请求的地址
//param.data 请求的参数
//param.success 请求成功的回调
//param.error 请求失败的回调
function send(param){
//随机函数名字,类似jquery
var random = "script" + Math.floor(Math.random() * 100000 + 100000);
//计时器Id,用于超时abort
var timeId = 0;
//创建script脚本
var script = document.createElement("script");
script.type = "text/javascript";
//绑定脚本错误事件
var onerror = script.onerror = function(){
//如果计时器是空,则表示请求成功了
if(!timeId)return false;
clearTimeout(timeId);
//回调用户错误函数
param.error();
//移除script标签以及对应成功函数
document.body.removeChild(script);
window.random = null;
};
//绑定全局回调成功函数
window[random] = function(){
if(!timeId)return false;
clearTimeout(timeId);
//将jsonp的参数列表,返回给用户的回调函数
try{
param.success.apply(null,arguments);
}
catch(e){
//用户回调执行出错,执行错误函数
param.error();
}
//移除script标签以及对应成功函数
document.body.removeChild(script);
window.random = null;
}
//超时则直接返回失败,这里设置了3秒
timeId = setTimeout(function(){
//触发onerror事件
onerror();
timeId = 0;
},3000);
//script的请求,一定是在最后
script.src = param.url + "?" + param.data + "&callback=" + random;
document.body.appendChild(script);
}
//返回请求接口
return send;
}();
//调用demo,这样看起来,就跟jquery的差不多了
__GetScript({
url : 'ad.com',
data : 'id=id1',
success : function(data){},
error : function(){}
});
2、超时、请求失败
服务器挂了,服务器卡住了,那广告位总不能显示空白吧?
用户第一次访问,服务器就挂了(这种表示无奈),显示一个加载失败的提示文案或者图标之类的,统一在广告位加上一个标识来处理
用户第一次访问成功过,但之后第二次访问的时候才挂的,那么可以考虑使用上一次成功的数据来展示
2.1 每次请求成功,缓存成功数据,格式采用
json
格式,旧版使用json2
来支持
2.2 IE使用userData
,标准浏览器用localStorage
2.3 合并新请求的数据与旧的缓存数据
//拉取数据成功
function getDataSucc(data,pos,cb_list){
//移除正在请求的提示
$(".adbase-ctn").css("background","none");
//获取本地缓存数据
var locData = getDataByLoc(pos);
//合并与覆盖最新数据到本地中
locData = extendData(locData,data);
//记录当前数据,JSON对应在旧浏览器需要用第三方库`json2`
LocalData.set(pos,JSON.stringify(locData));
//回调给用户
for(var i=0;i<cb_list.length;i++){
cb_list[i](true,locData);
}
}
//获取本地缓存数据
function getDataByLoc(pos){
//LocalData对象是操作userData和localStorage
var data = LocalData.get(pos);
if(!data)return {};
//从缓存中读取的字符串,转成json对象
return JSON.parse(data);
}
//合并新旧数据
function extendData(oldData,newData){
for(var key in newData){
//本地没有这个数据,合并
if(!oldData[key] || oldData[key].length < 1){
oldData[key] = newData[key];
continue;
}
//本地跟新数据都有,合并
if((oldData[key] && oldData[key].length) && (newData[key] && newData[key].length)){
oldData[key] = newData[key];
continue;
}
//新数据没有,本地数据有,不合并
if((oldData[key] && oldData[key].length) && (!newData[key] || newData[key].length < 1)){
continue;
}
//本地没有,新数据也没有
if((!newData[key] || newData[key].length < 1) && (!oldData[key] || oldData[key].length < 1)){
oldData[key] = [];
}
}
return oldData;
}
3、其它收尾细节
处理完请求和缓存这两块主要的,还有一些细节需要考虑
- 在请求成功后,统一上报数据,该请求可以稍微往后,用
setTimeout
- 在有数据的情况下(可能只是部分),需要针对没有数据的广告位进行显示失败的提示,例如:
//监测是否存在空数据的广告位
function checkNoDataCtn(){
//循环遍历容器是否有子元素
$(".adbase-ctn").each(function(index,item){
if($(item).contents().length < 1)$(item).css("background","url(http://res.nie.netease.com/comm/js/nie/util/img/error.png) center center no-repeat");
});
}
- IE7的
userData
的key
只支持的规则和定义变量一致,不能带有类似,
,;
这种分隔符 - 低版本的IE浏览器,即使
script
请求失败了,也不会调用onerror
事件,统一采用超时机制就好了
PS:更多代码详情,请参考:adbase
手机阅读请扫描下方二维码:
__GetScript 这个函数,里面的success方法没起作用。
1
555
1
1
1
1
1
1
1
1
1
1
1
1
1
不错哦,赞一个,求认识,求回访 http://www.xevip.cn
555
555
文章很好~!赞 http://www.viplinger.cn
12345678
1
12345678
12345678
12345678
12345678
12345678
gyskureniqpnfpnlsiiq
12345678
12345678
12345678
12345678
12345678
555
文章很好~!赞 欢迎回访:www.3gwb.com
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
1
1
1
1
1
1
1
1
555
1
1
1
1
1
1
1
1
1
555
1
555
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1