一:Jquery Ajax底层接口有:$.ajaxPrefilters、$.ajaxTransport、$.ajaxSettings、$ajaxSetup、$ajaxSettings;

  其中$.ajaxPrefilters 和 $.ajaxTransport是通过inspectPrefiltersOrTransports构造器来创建的;

$.ajaxPrefilters:是一个前置过滤器,在每个请求被$.ajaxTransport()和$.ajax()处理之前调用,设置自定义ajax选项或者修改现有的选项,简单说就是hack的  做法,但是比事件处理的hack的手法更加高明。可以用来处理参数,注册回调等。

例如:改变代理服务器的域请求

 $.ajaxPrefilter("+*", function( options ) {
if ( options.crossDomain ) {
options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
options.crossDomain = false;
}
});

$.ajaxTransport:是一个请求分发器,是发送请求的具体实现,比如xhr就用xmlhttprequest来实现,script就是通过head中插入script标签来实现.

例如:用来拦截发送的请求

 $.ajaxTransport("+*", function(options, originalOptions, jqXHR) {
return {
send: function(headers, completeCallback) {
var status = 404;
var statusText = "error";
var response = {
text: ""
};
var item = {            
url: "/paapi/v1/datapoints/pa",
data: data.groupsdatapoint
};
if (!item) {
console.log("require mock data: \n" + originalOptions.url);
} else {
status = 200;
statusText = "ok";
var data = item.data;
response.text = data;
}
setTimeout(function() {
completeCallback(status, statusText, response);
}, 0);
}
};
});

二: ajax的实现

  实现ajax的目的是什么?

实现ajax的目的主要是对不同的dataType的具体处理和实现,比如'jsonp'应该怎么处理,'script'怎么处理,'*'怎么处理;

对此ajax模块的做法是,提供一个基本的模块ajax,然后通过插件形式来实现对不同dataType的处理。

ajax暴露ajaxPrefilter: addToPrefiltersOrTransports( prefilters ) , ajaxTransport: addToPrefiltersOrTransports( transports )是给插件用的,可以注册自己的dataType处理函数。

其中prefilters={'jsonp': function() {}, '*': function(){}, 'script':function(){}}可能是这样的,ajax在每个请求发送之前,根据dataType调用prefilters中的函数进行预处理,然后调用transport中的对应函数来发送请求。

addToPrefiltersOrTransports()方法如下:

 function addToPrefiltersOrTransports(structure) {

      // dataTypeExpression is optional and defaults to "*"
return function(dataTypeExpression, func) { if (typeof dataTypeExpression !== "string") {
func = dataTypeExpression;
dataTypeExpression = "*";
} var dataType,
i = 0,
dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || []; if (jQuery.isFunction(func)) {
// For each dataType in the dataTypeExpression
while ((dataType = dataTypes[i++])) {
// Prepend if requested
if (dataType[0] === "+") {
dataType = dataType.slice(1) || "*";
(structure[dataType] = structure[dataType] || []).unshift(func); // Otherwise append
} else {
(structure[dataType] = structure[dataType] || []).push(func);
}
}
}
};
}

该函数功能就是把某一个dataType对应的处理函数func存进structure中,实际就是一个简单的注册事件。

 // Base inspection function for prefilters and transports
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("*");
}
}

该代码时取调用dataType对应的prefilters和transports函数而已。

Ajax完成一部请求的全过程:

  • 创建了一个jqXHR对象,这个对象就是ajax的返回值
  • 用deferred对象封装jqXHR对象,因此可以实现链式的异步操作:xhr.complete(x).success(x).errorl(x),这里的complete,success和error就是promise对象的add, done和fail的别名而已。
  • 调用函数inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ),那些插件注册的prefilters函数就在这里被调用了。
  • 做了一大对后续的处理,比如设置header参数,设置缓存cache
  • 调用inspectPrefiltersOrTransports( transports, s, options, jqXHR )函数发送请求
  • 定义了done函数,当请求发送结束之后做后续处理,包括调用convert转换结果、设置statusText,调用deferred.resolveWith触发异步回调等
  • 最后返回了jqXHR对象

Jquery 实现原理之 Ajax的更多相关文章

  1. 关于试用jquery的jsonp实现ajax跨域请求数据的问题

    我们在开发过程中遇到要获取另一个系统数据时,就造成跨域问题,这就是下文要说的解决办法: 先我们熟悉下json和jsonp的区别: 使用AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交 ...

  2. jQuery内部原理和实现方式浅析

    这篇文章主要介绍了jQuery内部原理和实现方式浅析,本文试图从整体来阐述一下jQuery的内部实现,需要的朋友可以参考下 这段时间在学习研究jQuery源码,受益于jQuery日益发展强大,研究jQ ...

  3. Jquery 实现原理深入学习(3)

    前言 1.总体结构 √ 2.构建函数 √ 3.each功能函数实现 √ 4.map功能函数实现 √ 5.sizzle初步学习 6.attr功能函数实现 7.toggleClass功能函数实现(好伤) ...

  4. [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...

  5. [jQuery]jQuery DataTables插件自定义Ajax分页实现

    前言 昨天在博客园的博问上帮一位园友解决了一个问题,我觉得有必要记录一下,万一有人也遇上了呢. 问题描述 园友是做前端的,产品经理要求他使用jQuery DataTables插件显示一个列表,要实现分 ...

  6. Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数:  ...

  7. [转]Spring3 MVC + jQuery easyUI 做的ajax版本用户管理

    原文地址:http://www.iteye.com/topic/1081739 上周写了篇基于spring3.0.5 mvc 简单用户管理实例 ( http://www.iteye.com/topic ...

  8. Comet 反Ajax: jQuery与PHP实现Ajax长轮询

    原文地址(http://justcode.ikeepstudying.com/2016/08/comet-%E5%8F%8Dajax-%E5%9F%BA%E4%BA%8Ejquery%E4%B8%8E ...

  9. 不借助jquery封装好的ajax,你能用js手写ajax框架吗

    不借助jquery封装好的ajax,你能手写ajax框架吗?最基础的ajax框架,一起来围观吧. .创建XMLHttpRequest对象 var xhr = new XMLHttpRequest(); ...

随机推荐

  1. iOS二维码条形码的制作

    - (IBAction)creatQRImage:(id)sender { [self.textField resignFirstResponder]; //这里是我放了个TextField的控件,但 ...

  2. Constraint where both columns cannot be null, but one can

    ALTER TABLE TableA ADD CONSTRAINT CK_BothDepartsNotNull CHECK (departA IS NOT NULL OR departB IS NOT ...

  3. OpenCV2.x自学笔记——最大类间方差法OTSU

    推荐用法:(参数勿动) threshold(gray,binary,0,255,CV_THRESH_OTSU+CV_THRESH_BINARY);

  4. Infix to posfix 自己写stack,没有()

    #include<iostream> #include<string> using namespace std; template<typename Type> s ...

  5. MT4 图表上设置字符

    ; int start() { //---- ObjectCreate(, , ); string str = "<"; string show ; ;i<x;i++) ...

  6. spring容器启动的加载过程(一)

    使用spring,我们在web.xml都会配置ContextLoaderListener <listener> <listener-class> org.springframe ...

  7. 【Machine Learning in Action --5】逻辑回归(LogisticRegression)

    1.概述 Logistic regression(逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性. 在经典之作<数学之美>中也看到了它用于广告预测,也就是根据某广告被 ...

  8. TextView赋值int型,并显示

    textview赋值int型采用text.setText(FPS+""); FPS为int型变量 或者在thread线程需要在主Activity中显示文字,可以调用: runOnU ...

  9. 安装gensim

    安装了一天的gensim,其中因为版本不一致等等各种问题纠结了好久,现记录如下: 正确安装方式: 1. 安装python2.7 2. 下载Python Extension Packages对应版本的n ...

  10. POJ 2062 HDU 1528 ZOJ 2223 Card Game Cheater

    水题,感觉和田忌赛马差不多 #include<cstdio> #include<cstring> #include<cmath> #include<algor ...