做有态度的前端团队

网易FEG前端团队

一个通用广告脚本数据加载的容错

最基本的需求

写一个通用的广告脚本文件,传递不同的广告ID,加载对应的数据出来,上报数据,最后显示出来

最简单的做法

每个站点,直接请求广告地址,带上不同参数,例如这样:

1
2
3
4
5
6
7
8
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";
}

以上做法存在的问题:

  1. 每个站点都需要记住请求的地址,万一地址改了,全都要改
  2. 每个站点,都需要自己去写请求,以及回调
  3. 每个站点,都需要自己去上报数据
  4. 请求失败了,怎么办?
  5. 请求时间很长,怎么办?

站点的使用,更应该关心的是:

  1. 统一的接口
  2. 只需要传ID和回调函数
  3. 返回需要的数据进行渲染页面
  4. 错误、失败、上报、超时等不需要关心

我们可以这样做

1、统一处理请求

采用类 jQuery的方式来进行jsonp请求,增加超时和错误监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//简易版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、超时、请求失败

服务器挂了,服务器卡住了,那广告位总不能显示空白吧?

  1. 用户第一次访问,服务器就挂了(这种表示无奈),显示一个加载失败的提示文案或者图标之类的,统一在广告位加上一个标识来处理

  2. 用户第一次访问成功过,但之后第二次访问的时候才挂的,那么可以考虑使用上一次成功的数据来展示

    2.1 每次请求成功,缓存成功数据,格式采用json格式,旧版使用json2来支持
    2.2 IE使用userData,标准浏览器用localStorage
    2.3 合并新请求的数据与旧的缓存数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//拉取数据成功
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
  • 在有数据的情况下(可能只是部分),需要针对没有数据的广告位进行显示失败的提示,例如:
1
2
3
4
5
6
7
8
//监测是否存在空数据的广告位
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的userDatakey只支持的规则和定义变量一致,不能带有类似,;这种分隔符
  • 低版本的IE浏览器,即使script请求失败了,也不会调用onerror事件,统一采用超时机制就好了

PS:更多代码详情,请参考:adbase

手机阅读请扫描下方二维码:

分享到:

    已有 85 条评论

    1. __GetScript 这个函数,里面的success方法没起作用。

    2. 不错哦,赞一个,求认识,求回访 http://www.xevip.cn

    3. 文章很好~!赞 http://www.viplinger.cn

      1. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      2. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      3. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      4. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      5. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      6. admin%0d%0aCRLF-Header:CRLF-Value

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      7. admin

        gyskureniqpnfpnlsiiq

      8. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      9. gyskureniqpnfpnlsiiq

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      10. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      11. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      12. admin

        12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

      13. 1

        555

    4. 文章很好~!赞 欢迎回访:www.3gwb.com

    5. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    6. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    7. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    8. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    9. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    10. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    11. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    12. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    13. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-52.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    14. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    15. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    16. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    17. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    18. 1

      1

    19. 1

      1

    20. 1

      1

    21. 1

      555

    22. 1

      1

    23. 1

      1

    24. 1

      1

    25. 1

      1

    26. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    27. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    28. 1

      1

    29. 1

      1

    30. 1

      555

    31. 1

      1

    32. 1

      555

    33. 1

      1

    34. 1

      1

    35. 1

      1

    36. 1

      1

    37. 1

      1

    38. 1

      1

    39. 1

      1

    40. 1

      1

    41. 1

      1

    42. 1

      1

    43. 1

      1

    44. 1

      1

    45. 1

      1

    46. 1

      1

    47. 1

      1

    48. 1

      1

    49. 1

      1

    50. 1

      1

    添加新评论

    ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif