模仿jquery封装ajax功能
需求分析
因为有时候想提高性能,只需要一个ajax函数,不想引入较大的jq文件,尝试过axios,可是get方法不支持多层嵌套的json,post方式后台接收方式似乎要变。。也许是我不太会用吧。。其实换个方式接收也没什么,只是习惯了JQ序列化参数。所以上网搜集了很多资料,同时也进一步了解了一点JQ。以下代码很多来自于网上,自己整合了一下。
封装代码
var Ajax = {};
(function($) {
function ajax(options) {
var str;
var xmlHttpRequest;
var timer;
if (window.XMLHttpRequest) {
xmlHttpRequest = new XMLHttpRequest();
} else {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
options = Object.assign({}, { type: "GET", processData: true, contentType: "application/x-www-form-urlencoded" }, options);
if (options.type.toUpperCase() !== "GET") {
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);
} else {
str = param(Object.assign(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);
}
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest.readyState === 4) {
clearInterval(timer);
if (xmlHttpRequest.status === 200) {
try {
// 如果是JSON格式,自动转换为JSON对象
options.success(JSON.parse(xmlHttpRequest.responseText));
} catch (e) {
options.success(xmlHttpRequest.responseText);
}
} else if (options.error) {
if (xmlHttpRequest.status === 304) {
options.error(xmlHttpRequest, "notmodified");
} else {
options.error(xmlHttpRequest, xmlHttpRequest.statusText);
}
}
}
};
//判断是否超时
if (options.timeout) {
timer = setTimeout(function() {
if (options.error) {
options.error(xmlHttpRequest, "timeout");
}
xmlHttpRequest.abort();
}, options.timeout);
}
}
// 把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;
for (i = 0; i < queryArr.length; i += 1) {
temp = queryArr[i].split("=");
key = temp[0];
value = temp[1];
obj[key] = value;
}
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);
}
// 为避免 Object.assign 不能使用
// 转载自 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign != "function") {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
"use strict";
if (target == null) { // TypeError if undefined or null
throw new TypeError("Cannot convert undefined or null to object");
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
$ = {
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: function(options) { return ajax(options); },
param: function(obj, traditional) { return param(obj, traditional); },
urlorQuerytoObject: function(urlorQuery) { return urlorQuerytoObject(urlorQuery); }
};
// 满足 jquery 的使用习惯
if (typeof window.$ === "undefined") {
window.$ = $;
}
})(Ajax);用法
高度模仿JQ。
// get请求
$.get("", {}, function(data) {})
// post请求
$.post("", {}, function(data) {})
// 更完整的ajax
$.ajax({
type: "post",
// 非必须,默认 get
url: "",
data: {},
// json格式
processData: true,
// 非必须,默认 true
contentType: "application/json;charsetset=UTF-8",
//非必须,默认 application/x-www-form-urlencoded
success: function(data) {},
timeout: 1000,
// 超时时间,非必须,如果设置了,超时且存在error函数则会调用
error: function(xhr, statusText) {// 非必须
// statusText: "notmodified","timeout", 或者其他xmlHttpRequest.statusText
}
});注意事项
1. 如果 " $ " 符号不能使用,请用 " Ajax " 替代,这个变量名若仍有冲突,请修改源代码首尾两行。
2. 如果返回的是json格式的字符串,会自动将字符串转为json对象传给success函数参数,其他情况均为字符串。
来自:https://www.cnblogs.com/kill370354/archive/2019/09/10/11497480.html
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!