资讯专栏INFORMATION COLUMN

ajax 源码解读之如何扩展 ajax 的功能

lavor / 3139人阅读

摘要:需求场景借助来自定义扩展功能。项目需求版本,错误打点,发起请求发生错误的时候前端需要向打点地址发送一个请求。项目需求防止请求的重复提交简单演示解决方案不重复发送相同请求测试代码

需求场景:借助 ajaxTransport 来自定义扩展功能。

项目需求:jQuery 版本: 1.10.2,错误打点,发起 jsonp 请求发生错误的时候前端需要向打点地址发送一个请求。

简单演示:
测试代码:

   $.ajax("http://google.com/a.js", {
       type: "GET",
       dataType: "jsonp",
       success: function(success, statusText, jqXHR){
           console.log("jsonp request success");
       },
       error: function(jqXHR, statusText, error){
           console.log("jsonp error");
       }
   });
   
   由于 1.10.2 版本的 jquery 并没有对创建的 script 监听错误事件,故无法调用 error 方法,故无法进一步将前端信息错误上报
   

解决方案:

   $.ajaxTransport("+script", function(s){
       // This transport only deals with cross domain requests
       var script,
            head = document.head || $("head")[0] || document.documentElement;
            
       return {
           send: function(_, callback) {
               
               script = document.createElement("script");
               
               script.async = true;
               
               if(s.scriptCharset){
                   script.charset = s.scriptCharset;
               }
               
               script.src = s.url;
               
               // Handle error
               script.onerror = function(err){
                   // Handle memory lead in IE
                   script.onload = script.onreadystatechange = null;
                   script.onerror = null;
                   
                   // Remove the script
                   if(script.parentNode){
                       script.parentnode.removeChild(script);
                   }
                   
                   // Dereference the script
                   script = null;
                   
                   if(err.type === "error"){
                       callback(404, err.type);
                   }
               }
               
               // Attach handlers for all browsers
               script.onload = script.onreadystatechange = function(_, isAbort){
                   
                   if(isAbort || !script.readyState || 
                   /loaded|complete/.test(script.readyState)){
                       // Handle memeory leak in IE
                       script.onload = script.onreadystatechange = null;
                       
                       // Remove the script
                       if(script.parentNode){
                           script.parentNode.removeChild(script);
                       }
                       
                       // Dereference the script
                       script = null;
                       
                       // Callback if not abort
                       if(!isAbort){
                           callback(200, "success");
                       }
                   }
               };
               
               // Cicumvent IE6 bugs with base elements (#2709 and #4378) by prepending
               // Use native DOM manipulation to avoid our domManip AJAX trickery
               head.insertBefore(script, head.firstChild);
           },
           
           abort: function(){
               if(script){
                   script.onload(undefined, true);
               }
           }
       };
   });

需求场景:借助 ajaxSetup 新增 dataType.

项目需求:需要从服务器获取 yaml 文件,然后解析该文件

简单演示:
解决方案:

   function parseYaml(text){
       console.log("You are parsing yaml file!");
       return "yaml" + text + "yaml";
   }
   $.ajaxSetup({
       accepts: {
           yaml: "application/x-yaml, text/yaml"
       },
       contents: {
           yaml: /yaml/
       },
       converters: {
           "text yaml": function(text){
               return parseYaml(text);
           }
       }
   });

测试代码:

   // 发送 dataType 为 yaml 的请求
   $.ajax({
       url: "http://google.com/helloworld.yaml",
       dataType: "yaml",
       success: function(data){
           console.log(data);
       }
   });

需求场景:借助 ajaxPrefilter 来自定义扩展功能。

项目需求:防止 ajax 请求的重复提交

简单演示:
解决方案:
var pendingRequests = {};

function storePendingRequest(key, jqXHR){

   pendingRequests[key] = true;
   jqXHR.pendingRequestKey = key;

}

function generatePendingRequestKey(options){

   return (options.type + options.url + options.dataType).toLowerCase().replace(/[^a-z0-9]/g, "");

}
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {

   
   // 不重复发送相同请求
   var key = generatePendingRequestKey(options);
   if (!pendingRequests[key]) {
       storePendingRequest(key, jqXHR);
   } else {
       // or do other
       jqXHR.abort();
   }
   
   var complete = options.complete;
   options.complete = function(jqXHR, textStatus) {
       // clear from pending requests
       pendingRequests[jqXHR.pendingRequestKey] = null;
       
       if ($.isFunction(complete)) {
           complete.apply(this, arguments);
       }
   };

});

测试代码:
for(var i = 0; i < 10; i++){

   var j = 0;
   $.ajax({
       url: "http://js.passport.qihucdn.com/5.0.2.js",
       type: "GET",
       dataType: "HTML",
       complete: function(){
           console.log("complete:" + j++);
       }
   });

}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79139.html

相关文章

  • Backbone源码解读(二)

    摘要:以为例构造函数的内容构造函数的内部一般会做以下几个操作各种给内部对象设置属性。为什么呢源码做出了解释。在里面会调用用户传入的回调函数并触发事件表示已经同步了。整个的源码事实上就是这两组东西。 1. 开场 强烈建议一边看着源码一边读本文章,本文不贴大段代码。源码地址。在写backbone应用的时候,说实话,大部分的时间都是在写这三个模块的内容。关于这三个模块的分析网上随随便便就能找到一堆...

    Sleepy 评论0 收藏0
  • Backbone源码解读(三)

    摘要:事件关于路由触发事件是通过两个函数来完成的,它们分别是和前者会检测路由是否发生了改变,如果改变了就会触发函数并调用函数,而后者会通过路由片段来找到相关的事件函数来触发。 注意:强烈建议一边阅读源码一边阅读本文。 终于到了backbone源码解读的最后一篇,这一篇和前面几篇时间上有一定的间隔(因为要回学校有一堆乱七八糟的事...)。在这一篇里面会讲解Bakcbone的sync & rou...

    feng409 评论0 收藏0
  • 前端基础进阶(十一):详细图解jQuery对象,以及如何扩展jQuery插件

    摘要:而在构造函数中,返回了的实例对象。在中直接返回过的实例,这里的是的真正构造函数最后对外暴露入口时,将字符与对等起来。因此当我们直接使用创建一个对象时,实际上是创建了一个的实例,这里的正真构造函数是原型中的方法。 showImg(https://segmentfault.com/img/remote/1460000008749398); 早几年学习前端,大家都非常热衷于研究jQuery源...

    RebeccaZhong 评论0 收藏0
  • backbone源码解读

    摘要:个人认为,读懂老牌框架的源代码比会用流行框架的要有用的多。另外,源代码中所有的以开头的方法,可以认为是私有方法,是没有必要直接使用的,也不建议用户覆盖。 写在前面 backbone是我两年多前入门前端的时候接触到的第一个框架,当初被backbone的强大功能所吸引(当然的确比裸写js要好得多),虽然现在backbone并不算最主流的前端框架了,但是,它里面大量设计模式的灵活运用,以及令...

    Kross 评论0 收藏0
  • backbone源码解读

    摘要:个人认为,读懂老牌框架的源代码比会用流行框架的要有用的多。另外,源代码中所有的以开头的方法,可以认为是私有方法,是没有必要直接使用的,也不建议用户覆盖。 写在前面 backbone是我两年多前入门前端的时候接触到的第一个框架,当初被backbone的强大功能所吸引(当然的确比裸写js要好得多),虽然现在backbone并不算最主流的前端框架了,但是,它里面大量设计模式的灵活运用,以及令...

    wangxinarhat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<