非常适合新手的jq/zepto源码分析07---ajax的封装
复习下ajax吧!
1.创建XMLHttpRequest对象
xmlhttp=new XMLHttpRequest();
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); //ie7以下
xmlhttp.open("GET","test1.txt",true); 参数 method,url,async()
xmlhttp.send();
xmlhttp.setRequestHeader(name,value);
Accept: 浏览器能够处理的内容类型。
Accept-Charset: 浏览器能显示的字符集。
Accept-Language: 浏览器当前设置的语言。
Connection: 浏览器与服务器之间连接的类型
Cookie: 当前页面设置的任何Cookie.
Host: 发出请求的页面所在的域。
Referer: 发出请求的页面的URI
User-Agent: 浏览器的用户代理字符串。
Content-type:请求数据类型
Cache-Control :指定请求响应的缓存机制
Content-Length:内容长度
Date:发送请求时间
等
xmlhttp.onreadystatechange 状态改变出发该函数
xmlhttp.readyState 状态
0 : 请求未初始化
1 : 服务器连接已建立
2 : 请求已接收
3 : 请求处理中
4 : 请求已完成
xmlhttp.status
2xx : 成功
3xx : 转向或者缓存
4xx : 未找到页面等
5xx : 服务器报错
$.ajaxSettings = {
// 默认请求类型
type: 'GET',
// 请求执行前的回调函数
beforeSend: empty,
// 执行成功后的回调函数
success: empty,
// 服务器返回错误的回调函数
error: empty,
// 请求完成的回调函数
complete: empty,
// 回调函数的上下文
context: null,
// 是否绑定一个全局事件
global: true,
// Transport
xhr: function () {
return new window.XMLHttpRequest()
},
// 接受的类型
accepts: {
script: 'text/javascript, application/javascript, application/x-javascript',
json: jsonType,
xml: 'application/xml, text/xml',
html: htmlType,
text: 'text/plain'
},
// 是否是跨域
crossDomain: false,
// 请求超时时间
timeout: 0,
// 是否序列化
processData: true,
// 是否缓存
cache: true,
dataFilter: empty
}
$.ajax = function(options){
var settings = $.extend({}, options || {}),
deferred = $.Deferred && $.Deferred(), //检查是有延时函数,有则创建一个
urlAnchor, hashIndex
//设置默认参数
for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]
//创建Event对象,初始化ajaxStart事件,并且执行该事件
ajaxStart(settings)
//检查是否跨域
if (!settings.crossDomain) {
urlAnchor = document.createElement('a')
urlAnchor.href = settings.url
// cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049
urlAnchor.href = urlAnchor.href
settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host)
}
if (!settings.url) settings.url = window.location.toString() //如果不存在url,直接提交到当前路径
if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex) //去掉hash #后面的hash
//序列化数据,如果是get/jsonp,直接把数据绑定在url上面
serializeData(settings)
var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) // 查看url是否有 callback定义 如果定义了,就设置为jsonp请求
if (hasPlaceholder) dataType = 'jsonp'
//如果不缓存,就在后面添加当前请求时间,每次请求不同就不会缓存
if (settings.cache === false || (
(!options || options.cache !== true) &&
('script' == dataType || 'jsonp' == dataType)
))
settings.url = appendQuery(settings.url, '_=' + Date.now())
//如果是jsonp,则url后面添加 &callback=?
if ('jsonp' == dataType) {
if (!hasPlaceholder)
settings.url = appendQuery(settings.url,
settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')
return $.ajaxJSONP(settings, deferred)
}
var mime = settings.accepts[dataType], //获取接收的数据类型
headers = { },
setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },
protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, //得到url协议或者当前协议
xhr = settings.xhr(), //获得xmlthttprequest对象
nativeSetHeader = xhr.setRequestHeader, //获取设置 头部信息的方法
abortTimeout
if (deferred) deferred.promise(xhr) //设置延时器
if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') //设置当前请求为ajax 异步请求
setHeader('Accept', mime || '*/*') //设置可接收的数据类型
if (mime = settings.mimeType || mime) {
if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]
xhr.overrideMimeType && xhr.overrideMimeType(mime) //设置可接收的类型
}
if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))
//设置提交数据的方式
//application/x-www-form-urlencode 将提交的数据进行urlencode (form表单提交的默认方式) ?name=value1&name2=value2
//multipart/form-data 数据每一条都用 boundary 分割符隔开 (form传输file文件时候 一般用这个)
//application/json 直接提交json
setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') //设置提交方式
if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) //设置头部信息
xhr.setRequestHeader = setHeader
//监听 readyState 改变的函数
xhr.onreadystatechange = function(){
// 当readyState 为4 时候请求完成
if (xhr.readyState == 4) {
//清除该监听
xhr.onreadystatechange = empty
clearTimeout(abortTimeout) //清除超出时间的 定时器
var result, error = false
//200-300 成功
//304 检查响应的last-modified 和 if-modified-since 如果相等 直接用本地缓存的数据
//
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'))
//接受的数据类型 script/xml/json
if (xhr.responseType == 'arraybuffer' || xhr.responseType == 'blob') //二进制数据
result = xhr.response
else {
result = xhr.responseText //文本数据
try {
// 这里是要用 setting 配置里面的 dataFilter和content 来处理数据
result = ajaxDataFilter(result, dataType, settings)
if (dataType == 'script') (1,eval)(result) // (1,eval) 兼容低版本IE 其实就是eval
else if (dataType == 'xml') result = xhr.responseXML //如果是xml 直接返回xml
else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) //非空的话 直接解析result
} catch (e) { error = e }
if (error) return ajaxError(error, 'parsererror', xhr, settings, deferred) //错误,调用setting里面error
}
ajaxSuccess(result, xhr, settings, deferred) //调用成功函数
} else {
ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) //错误,调用setting里面的error
}
}
}
//如果在 setting 的before函数中 返回false 直接返回,断开请求
if (ajaxBeforeSend(xhr, settings) === false) {
xhr.abort()
ajaxError(null, 'abort', xhr, settings, deferred)
return xhr
}
var async = 'async' in settings ? settings.async : true
//创建一个请求
xhr.open(settings.type, settings.url, async, settings.username, settings.password)
//添加请求字段信息
if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name]
//nativeSetHeader 设置头部信息 xhr.setRequestHeader(name,value)
for (name in headers) nativeSetHeader.apply(xhr, headers[name]) //headers[name] ->[name,value]
// 超时后执行
if (settings.timeout > 0) abortTimeout = setTimeout(function(){
xhr.onreadystatechange = empty
xhr.abort()
ajaxError(null, 'timeout', xhr, settings, deferred)
}, settings.timeout)
// 发送数据返回,当前xmlHttpRequrest对象
xhr.send(settings.data ? settings.data : null)
return xhr
}
这个是主要的对象ajax的封装。
代码仅供参考,具体功能可以自己扩展。
http://www.cnblogs.com/jiebba/p/6529854.html
http://www.cnblogs.com/jiebba 我的博客,来看吧!
如果有错误,请留言修改下 哦!
非常适合新手的jq/zepto源码分析07---ajax的封装的更多相关文章
- 非常适合新手的jq/zepto源码分析08---ajax的封装
1.现在看看对JSONP的封装 $.ajaxJSONP = function(options, deferred){ if (!('type' in options)) return $.ajax(o ...
- 非常适合新手的jq/zepto源码分析06 -- 事件模型
复习下事件的有关内容: 1.现在用的绑定/删除: obj.addEventListener(type,fn,false) obj.removeEventListener(type) obj.attac ...
- 非常适合新手的jq/zepto源码分析05
zepto的原型 $.fn 属性: constructor //构造行数 forEach: emptyArray.forEach, //都是原生数组的函数reduce: emptyArray.re ...
- 非常适合新手的jq/zepto源码分析03
zepto.fragment = function(html, name, properties) { var dom, nodes, container // 如果是简单的标签<div> ...
- 非常适合新手的jq/zepto源码分析04
$.extend = function(target){ var deep, args = slice.call(arguments, 1) if (typeof target == 'boolean ...
- 非常适合新手的jq/zepto源码分析01
(function(global, factory) { // 查看这里是不是定义成模块,如果定义模块就返回 一个模块 if (typeof define === 'function' &&a ...
- 非常适合新手的jq/zepto源码分析02
function isPlainObject(obj) { return isObject(obj) && !isWindow(obj) && Object.getPr ...
- zepto源码分析系列
如果你也开发移动端web,如果你也用zepto,应该值得你看看.有问题请留言. Zepto源码分析-架构 Zepto源码分析-zepto(DOM)模块 Zepto源码分析-callbacks模块 Ze ...
- 一个普通的 Zepto 源码分析(二) - ajax 模块
一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...
随机推荐
- 基于Web的Kafka管理器工具之Kafka-manager安装之后第一次进入web UI的初步配置(图文详解)
前期博客 基于Web的Kafka管理器工具之Kafka-manager的编译部署详细安装 (支持kafka0.8.0.9和0.10以后版本)(图文详解) 基于Web的Kafka管理器工具之Kafka- ...
- node-rsa加密,java解密调试
用NODE RSA JS 加密解密正常,用JAVA RSAUtils工具类加密解密正常.但是用node加密玩的java解密不了.原因:node默认的是 DEFAULT_ENCRYPTION_SCHEM ...
- 17 C#中的循环执行 while循环
在编程中有代码的执行主要有三种方式.(1)顺序执行,也就是一条语句一条语句按顺序执行:(2)条件执行,也就是if...else.当某种条件满足时执行一些代码:(3)循环执行,就是当某种条件满足的时候, ...
- Java常见面试问题: equals()与hashCode()的使用
目录 1 equals()与'=='的区别 2 equals()方法的重写规则 3 为什么重写equals()的同时还需要重写hashCode() 4 JDK 7中对hashCode()方法的改进 5 ...
- linux创建ftp用户以及指定目录问题
linux创建ftp用户以及指定目录问题 创建用户命令:如我的目录是根目录下的 MyWeb 用户名:xdh2571 #useradd -G ftp -d /MyWeb -M xdh2571#passw ...
- Java&Xml教程(八)使用JDOM将Java对象转换为XML
在前面的教程中我们学习了如何使用JDOM解析和修改XML文件内容,本节介绍如何将Java对象转换为XML数据并生成文件. JDOM的Document类提供了便捷的方法创建元素和属性,XMLOutput ...
- 第五届蓝桥杯校内选拔第六题_(dfs)
你一定听说过“数独”游戏.如[图1.png],玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个同色九宫内的数字均含1-9,不重复. 数独的答案都是唯一的,所以 ...
- 搭建linux环境:如何在vmware安装linux虚拟机??
本来不想再整一遍的,奈何分布式压测呀,呀呀呀呀呀呀 1.安装linux虚机 (1)在桌面上双击VMware Workstation图标后启动虚拟机,鼠标单击文件,选择新的虚拟机: (2)单击“next ...
- vue基础---模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解 ...
- 00Extensible Markup Language
Extensible Markup Language XML(Extensible Markup Language)可扩展标记语言是用来网络数据的组织结构,传输及存储.