模仿JQuery封装ajax功能
需求分析
因为有时候想提高性能,只需要一个ajax函数,不想引入较大的jq文件,尝试过axios,可是get方法不支持多层嵌套的json,post方式后台接收方式似乎要变。。也许是我不太会用吧。。其实换个方式接收也没什么,只是习惯了JQ序列化参数。所以上网搜集了很多资料,同时也进一步了解了一点JQ。以下代码很多来自于网上,自己整合了一下。
封装代码
/**
* @Description: 模仿jQuery封装简单的ajax功能。
* @Author: kill370354@qq.com
**/ var Ajax = {};
(function($) {
function ajax(options) {
var str;
var xmlHttpRequest;
var timer;
if (window.XMLHttpRequest) {
xmlHttpRequest = new XMLHttpRequest();
} else {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} var source = {
type: "GET",
processData: true,
contentType: "application/x-www-form-urlencoded"
};
options = mergeObject(source, options);
if (options.contentType.replace(/(^\s*)|(\s*$)/g, "") === "application/json") {
options.processData = false;
}
xmlHttpRequest = mergeObject(xmlHttpRequest, options.xhrFields);
if (options.type.toUpperCase() === "GET") {
str = param(mergeObject(urlorQuerytoObject(options.url), options.data));
if (options.url.indexOf("?") !== -1) {
options.url = options.url.substr(0, options.url.indexOf("?"));
}
xmlHttpRequest.open("GET", options.url + "?" + str, true);
xmlHttpRequest.send(null);
} else {
xmlHttpRequest.open(options.type.toUpperCase(), options.url, true);
xmlHttpRequest.setRequestHeader("Content-type", options.contentType);
if (options.processData) {
str = param(options.data);
} else {
str = options.data;
}
xmlHttpRequest.send(str);
}
xmlHttpRequest.onreadystatechange = function() {
var textStatus = "";
if (xmlHttpRequest.readyState === 4) {
clearInterval(timer);
if ((xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) || xmlHttpRequest.status === 304) {
if (xmlHttpRequest.status === 304) {
textStatus = "notmodified";
} else {
textStatus = "success";
}
try {
// 如果是JSON格式,自动转换为JSON对象
options.success(JSON.parse(xmlHttpRequest.responseText), textStatus);
} catch (e) {
options.success(xmlHttpRequest.responseText, textStatus);
}
} else {
textStatus = "error";
if (typeof options.error === "function") {
options.error(xmlHttpRequest, textStatus);
}
}
if (typeof options.complete === "function") {
options.complete(xmlHttpRequest, textStatus);
}
}
};
//判断是否超时
if (typeof options.timeout === "number") {
timer = setTimeout(function() {
if (typeof options.error === "function") {
options.error(xmlHttpRequest, "timeout");
options.complete(xmlHttpRequest, "timeout");
}
if (typeof options.complete === "function") {
options.complete(xmlHttpRequest, "timeout");
}
xmlHttpRequest.abort();
}, options.timeout);
}
} // 合并对象
function mergeObject(target) {
if (target == null) {
throw new TypeError("Cannot convert undefined or null to object");
}
target = Object(target);
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index];
if (source != null) {
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
}
return target;
} // 把url中的查询字符串转为对象,主要是想当方式为get时,用data对象的参数覆盖掉url中的参数
function urlorQuerytoObject(urlorQuery) {
var queryArr = [];
var urlSplit = urlorQuery.split("?");
queryArr[0] = urlSplit[0];
if (urlSplit[1]) {
queryArr[0] = urlSplit[1];
}
queryArr = queryArr[0].split("&");
var obj = {};
var i = 0;
var temp;
var key;
var value;
while (i < queryArr.length) {
temp = queryArr[i].split("=");
key = temp[0];
value = temp[1];
obj[key] = value;
i++;
}
return obj;
} // 序列化参数
// 转载自 https://www.jianshu.com/p/0ca22d53feea
function param(obj, traditional) {
if (traditional === "undefined") {
traditional = false;
}
var rbracket = /\[\]$/,
op = Object.prototype,
ap = Array.prototype,
aeach = ap.forEach,
ostring = op.toString; function isFunction(it) {
return ostring.call(it) === "[object Function]";
} function isArray(it) {
return ostring.call(it) === "[object Array]";
} function isObject(it) {
return ostring.call(it) === "[object Object]";
} function buildParams(prefix, obj, traditional, add) {
var name;
if (isArray(obj)) {
// Serialize array item.
aeach.call(obj, function(v, i) {
if (traditional || rbracket.test(prefix)) {
// Treat each array item as a scalar.
add(prefix, v);
} else {
// Item is non-scalar (array or object), encode its numeric index.
buildParams(
prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
v,
traditional,
add
);
}
});
} else if (!traditional && isObject(obj)) {
// Serialize object item.
for (name in obj) {
buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
}
} else {
// Serialize scalar item.
add(prefix, obj);
}
} // Serialize an array of form elements or a set of
// key/values into a query string
function jollyparam(a, traditional) {
var prefix,
s = [],
add = function(key, valueOrFunction) {
// If value is a function, invoke it and use its return value
var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);
};
// If an array was passed in, assume that it is an array of form elements.
if (isArray(a)) {
// Serialize the form elements
aeach.call(a, function(item) {
add(item.name, item.value);
});
} else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
for (prefix in a) {
buildParams(prefix, a[prefix], traditional, add);
}
}
// Return the resulting serialization
return s.join("&");
} return jollyparam(obj, traditional);
} $ = {
get: function(url, data, success) {
return ajax({ url: url, data: data, success: success });
},
post: function(url, data, success) {
return ajax({
type: "POST",
url: url,
data: data,
success: success
});
},
ajax: ajax,
param: param,
urlorQuerytoObject: urlorQuerytoObject,
mergeObject: mergeObject
}; // 满足 JQuery 的使用习惯
if (typeof window.$ === "undefined") {
window.$ = $;
}
})(Ajax);
用法
高度模仿JQ。
// get请求
$.get("", {}, function(data) {}); // post请求
$.post("", {}, function(data) {}); // 更完整的ajax
$.ajax({
type: "post", // 非必须,默认 get
url: "",
data: { },
xhrFields: {
// 非必须,自定义 XHR 对象属性
withCredentials: true
},
processData: true, // 非必须,默认 true
contentType: "application/x-www-form-urlencoded", // 非必须,默认 application/x-www-form-urlencoded
success: function(responseData, textStatus) {
// textStatus : "success"、"notmodified"
},
// timeout: 1, // 非必须,超时毫秒数,如果设置了,超时且存在error函数则会调用
error: function(xhr, textStatus) {
// 非必须
// textStatus: "error"、"timeout"
},
complete: function(xhr, textStatus) {
// 非必须,无论成败最后均调用
// textStatus: "success"、"notmodified"、"error"、"timeout"
}
});
注意事项
1. 如果 " $ " 符号不能使用,请用 " Ajax " 替代,这个变量名若仍有冲突,请修改源代码首尾两行。
2. 如果返回的是json格式的字符串,会自动将字符串转为json对象传给success函数参数,其他情况均为字符串。
第一次发博客,经验不足,引用了许多别人的代码,只是这功能已经缠了我很多天了,今天终于相对完善了,如有不妥,还请多多指教!
模仿JQuery封装ajax功能的更多相关文章
- Ajax学习(二):模仿jQuery的Ajax封装工具
通过上一节的学习,基本了解Ajax的使用, 但是这样使用很麻烦,这里封装ajax为一个方法,作为一个ajax工具,传入相应参数就可以实现ajax的使用. 模仿jQuery的Ajax. 如下是jQuer ...
- 自己使用Jquery封装各种功能分享
自己使用Jquery封装各种功能分享: 左右滚动图片 瀑布流 流动显示列表 广告切换 头像切换And广告切换 获取搜索引擎的来源关键字 上面列表中展示的功能都是使用jquery进行封装实现的,希望大家 ...
- Jquery封装ajax
Jquery封装ajax Load方法 <!-- 将jquery.js导入进来 --> <script type="text/javascript&qu ...
- 模仿jQuery的ajax的封装
/* * 我们使用了ajax 的xmlHttpRequest 跟服务器进行交互. * * 交互了有四个基本步骤 * 1:创建对象 * 2:建立连接 * 3:发送请求 * 4:接收数据 * * 这些操作 ...
- Struts2 整合jQuery实现Ajax功能(1)
技术领域非常多东西流行,自然有流行的道理.这几天用了jQuery,深感有些人真是聪明绝顶,能将那么多技术融合的如此完美. 首先明白个概念: jQuery是什么:是使用javascript语言开发的,用 ...
- js源码 模仿 jquery的ajax的获取数据(get,post )的请求封装
function ajax(obj){ // 默认参数 var defaults = { type : 'get', data : {}, url : '#', dataType : 'text', ...
- Struts2 整合jQuery实现Ajax功能(2)
1.1.1 Action利用struts2-json-plugin-X.X.X.jar响应Json格式信息: 1. function removerecordbyid(recordid) ...
- JQuery封装ajax的方法
1.$.post方法 $.post(url[,data][,callback][,type]) url:请求的后台程序地址 data:发送到后台的数据 callback:载入成功时回调函数,该函数参数 ...
- Jquery和Ajax的关系!
Jquery是一种JavaScript框架,而Ajax(Asynchronous JavaScript and XML)是异步JavaScript和XML. Jquery是JavaScript的框架, ...
随机推荐
- Django前后端分离跨域请求问题
一.问题背景 之前使用django+vue进行前后端分离碰到跨域请求问题,跨域(域名或者端口不同)请求问题的本质是由于浏览器的同源策略导致的,当请求的响应不是处于同一个域名和端口下,浏览器不会接受响应 ...
- css 文字对齐
// html <div>姓名</div> <div>手机号码</div> <div>账号</div> <div>密 ...
- windows之cmd常用命令
一.简单介绍 CMD全称command,即命令提示符,是内置在windows图形操作系统内的磁盘操作系统,通过CMD可以方便用户查询比较复杂的信息或快速查找实现某些功能等,比如说打开文件.系统设置等操 ...
- 每天一个linux命令:less(14)
less less命令的作用与more十分相似,都可以用来浏览文字档案的内容,less 在查看之前不会加载整个文件 .用less命令显示文件时,用PageUp键向上翻页,用PageDown键向下翻页. ...
- ckeditor实现WORD粘贴图片自动上传
自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了.一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器) ...
- 【LeetCode 75】颜色分类
题目链接 [题解] 维护一个左边界l和一个右边界r 其中0..l-1都是'0' 而 r+1..n-1都是'2' 我们令i=l;i<=r; 枚举每一个a[i]; ①如果a[i]=2.那么把a[i] ...
- 修改element中v-loading的自定义图片
/*elementui loading css 覆盖 开始*/ .el-loading-spinner .circular{ width: 42px; height: 42px; animation: ...
- python中chr()函数和ord()函数的用法
一,chr()函数 格式:Chr(<数值表达式>) 说明:函数返回值类型为String,其数值表达式值取值范围为0~255. 例如:Print Chr(78),结果显示:N. ...
- SyntaxError: missing ] after element list
在前端页面js报错,找了很久没找到原因. 后来发现是后台向前端输出json字符串,而前端接收是html格式,需要将后台json字符串改成正常字符串就可以输出,或者通过ajax的方式接收json字符串.
- 109、TensorFlow计算张量的值
# 当计算图创建成功时 # 你就可以运行这个计算图,然后生成一个新的张量 # 并且得到这个张量指向的计算图中具体的数值 #这个功能在debug的时候非常有必要 #最简单获得张量具体值的方法是使用Ten ...