jQuery如何管理、扩展AJAX请求
沉沙 2018-05-28 来源 : 阅读 1622 评论 0

摘要:jQuery1.5以后,AJAX模块提供了三个新的方法用于管理、扩展AJAX请求,分别是:.前置过滤器 jQuery. ajaxPrefilter、请求分发器 jQuery. ajaxTransport、类型转换器 ajaxConvert,希望阅读本篇文章以后大家有所收获,加深大家对jQuery的理解。

jQuery1.5以后,AJAX模块提供了三个新的方法用于管理、扩展AJAX请求,分别是:

1.前置过滤器 jQuery. ajaxPrefilter

2.请求分发器 jQuery. ajaxTransport,

3.类型转换器 ajaxConvert

源码结构:

jQuery.extend({
 
    /**
     * 前置过滤器
     * @type {[type]}
     */
    ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
 
    /**
     * 请求分发器
     * @type {[type]}
     */
    ajaxTransport: addToPrefiltersOrTransports(transports),
 
    
     ...........................
});

可见这2个方法是通过私有方法addToPrefiltersOrTransports通过curry手段构造的,分别是保持了prefilters与transports的引用

 

来个简单的模拟这个结构

var prefilters = 2;
var addToPrefiltersOrTransports = function(prefilters) {
    return function(b) {
        return prefilters + b;
    }
}
var ajaxPrefilter = addToPrefiltersOrTransports(prefilters)
 
ajaxPrefilter(1) //3

可见ajaxPrefilter就维持了addToPrefiltersOrTransports返回函数的引用了,这种就是闭包的手法了,这也是JS的开发人员都需要掌握的

好处就是合并多个参数,当然因为维持引用代价就是一点点性能消耗

 

当然jQuery不是传递的简单类型处理,还可以传递的一个引用类型的回调函数,所以针对ajaxPrefilter方法放闭包构件就需要做一些处理了

填充prefilters处理器

var prefilters = {};
var addToPrefiltersOrTransports = function(structure) {
 
    return function(func) {
        structure['*'] = func;
    }
}
var ajaxPrefilter = addToPrefiltersOrTransports(prefilters)
 
 
ajaxPrefilter(function(options){
    return {
        send:function(){
 
        },
        callback:function(){
 
        }
    }
})

其实说白了就是把对应的方法制作能函数的形式填充到prefilters或者transports对应的处理包装对象中

要用的时候直接执行,每个函数都保持着各自的引用

这种写法的好处自然是灵活,易维护,减少代码量

还有我们经常的使用的,jQuery的代码很简练,比如合并多个方法的创建等等

jQuery.each([
        "tabIndex",
        "readOnly",
        "maxLength",
        "contentEditable"
    ], function() {
        jQuery.propFix[this.toLowerCase()] = this;
    });

 

所以此时的prefilters中的结构就是

prefilters = {
        '*': function() {
            return {
                send: function() {
 
                },
                callback: function() {
 
                }
            }
        }
    }


回归重点,那么引入ajaxPrefilter与ajaxTransport的作用是干嘛?

前置过滤器和请求分发器在执行时,分别遍历内部变量prefilters和transports,这两个变量在jQuery加载完毕后立即初始化,从过闭包的方法填充这个2个对象

 

ajaxPrefilter与ajaxTransport都是通过inspectPrefiltersOrTransports构建器

prefilters中的前置过滤器在请求发送之前、设置请求参数的过程中被调用,调用prefilters的是函数inspectPrefiltersOrTransports;

巧妙的是,transports中的请求分发器在大部分参数设置完成后,也通过函数inspectPrefiltersOrTransports取到与请求类型匹配的请求分发器:

function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
 
    var inspected = {},
        seekingTransport = (structure === transports);
 
    function inspect(dataType) {
        var selected;
        inspected[dataType] = true;
        jQuery.each(structure[dataType] || [], function(_, prefilterOrFactory) {
            var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
            if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
                options.dataTypes.unshift(dataTypeOrTransport);
                inspect(dataTypeOrTransport);
                return false;
            } else if (seekingTransport) {
                return !(selected = dataTypeOrTransport);
            }
        });
        return selected;
    }
 
    return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
}

遍历structure[dataType]数组,并执行回调 
prefilterOrFactory为函数数组元素 
执行该函数如果返回的结果dataTypeOrTransport是字符串且时prefilters且没有被inspected过 
就给options.dataTypes数组头部添加该字符串 
继续递归dataTypeOrTransport(当我们使用json/jsonp的时候会返回“script”,于是会执行“script”相关的回调) 
如果是transport就返回dataTypeOrTransport的假结果

 

前置过滤器 prefilters

简单的说就是一种hack的做法,只是说比起事件的那种hack写的手法实现更为高明

我们可以看看针对prefilters的方法其实就是dataType为 script,json,jsonp的处理

当我们动态加载脚本文件比如

$.ajax({
    type     : "GET",
    url      : "test.js",
    dataType : "script"
});

所以在inspectPrefiltersOrTransports方法中prefilters[script]能找到对应的处理方法,所以就会执行

例如script的hack,要强制加上处理缓存的特殊情况和crossDomain

因为设置script的前置过滤器,script并不一定意思着跨域

跨域未被禁用,强制类型为GET,不触发全局时间

jQuery.ajaxPrefilter("script", function(s) {
    if (s.cache === undefined) {
        s.cache = false;
    }
    if (s.crossDomain) {
        s.type = "GET";
    }
});

所以prefilters就是在特定的环境针对特定的情况做一些必要的兼容的处理

 

 

请求分发器 transports

请求分发器顾名思义发送请求,那么底层的ajax发送请求是通过send方法

xhr.send();

但是jQuery对send方法做了拆分,把对应的处理放到了transports中了

那么transports对象也是类似前置处理器通过jQuery.ajaxTransport构建

例如script,send,abort方法

返回出transports方法

transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端jQuery频道!


本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程