关于ajax ,其实有几点比较有趣:
- ajax中发挥“主要作用”的就是它的 send属性 ,这个是调用ajax方法时“自动调用”的,但是自己封装时主要代码,比如发送请求、处理数据、请求方法判断等要写在这里;
- 关于post请求调用ajax,open中写的是method、url、true,要加上请求头setRequestHeader,send里面写json处理的数据data(这个send是method调用的send,和上面那个不一样性质)
- 关于get请求调用ajax,open中相比post方式,url变成了url+处理过后的data(格式:?xxx=xxx&xxx=xxx),没有请求头,send中写null
- 前面我有文章说常用的跨域方法有jsonp和cors,其中最为开发者“喜爱”的应该是jsonp了。jsonp的方式有些特别,它主要利用了“ script、img等标签支持跨域 ”的特性,去构造script标签,在src里传参,和回调
不说了,直接上代码。
es5方式(普通方式)
新建文件 ajax.js
function Ajax(obj){
this.method = obj.method || 'GET';
this.url = obj.url || '';
this.callback = obj.callback || '';
this.data = obj.data || '';
this.dataType = obj.dataType || 'json';
};
Ajax.prototype.send = function(method,url,callback,data,dataType){
var method = method || this.method;
var data = data || this.data;
var url = url || this.url;
var callback = callback || this.callback;
var dataType= dataType || this.dataType;
var xhr = new XMLHttpRequest();
if(method.tolocaleLowerCase() === 'get'){ //如果是get方法,需要把data中的数据转化作为url传递给服务器
if(typeof data === 'object'){
var data_send = '?';
for(var key in data){
data_send+=key+'='+data[key];
data_send+='&';
}
data_send = data_send.slice(0,-1);
// console.log(data_send);
}
xhr.open(method,url+data_send,true);
xhr.send(null);
}else if(method.tolocaleLowerCase() === 'post'){//如果是post,需要在头中添加content-type说明
xhr.open(method,url,true);
xhr.setRequestHeader('Content-Type','application/json');
xhr.send(JSON.stringify(data));//发送的数据需要转化成JSON格式
}else {
console.log('未识别的方法? '+method);
return fasle;
}
xhr.onreadystatechange = function(){ // 注册回调函数
if(xhr.readyState === 4 && xhr.status === 200){
// callback(xhr.responseText); //——这一步不能直接这么写->缺少判断:jsonp方式的回调和其他方式不一样
if(dataType == "json"){
callback(xhr.responseText);
}else{
var oScript = document.createElement('script');
document.body.appendChild(oScript);
var callbackname = 'mxcb'; //这个callback的name好像是要和后端返回的保持一致
oScript.src = url + "?" + data_send +'&callback='+ callbackname;
window[callbackname] = function(data) {
callback(data);
document.body.removeChild(oScript);
}
}
}else{
alert('请打开服务器运行!');
}
}
( 传参,要么&拼在url后面(get形式),要么JSON形式send给后端(post形式) )
关于slice方法:
start 可选。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
所以:slice(0,-1);就是找这个字符串/数组的所有元素!
然后我们就可以在HTML页面里去疯狂调用了:
<script src="ajax.js"></script>
<script>
Ajax({methods:'GET',url:'xxx',function(res){
//...
}})
</script>
es6方式
提起es6,那最先想到的基本就是Promise:
function $ajax(options){
options=Object.assign({
url:'',
method:'POST',
data:null,
headers:{}
},options);
return new Promise((resolve,reject)=>{
let xhr=new XMLHttpRequest;
xhr.open(options.url,options.method);
Object.keys(options.headers).forEach(key=>{
xhr.setRequestHeader(key,options.headers[key]);
});
xhr.onreadystatechange=()=>{
if(xhr.readyState===4){
if(/^(2|3)\d{2}$/.test(xhr.status)){
resolve(JSON.parse(xhr.responseText));
return;
}
reject(xhr);
}
};
xhr.send(options.data);
});
}
Object.assign()方法:
复制、赋值,其用法如上:把第二个参数的值赋给第一个参数(遍历对应赋值)
Object.keys()方法:
返回给定对象所有可枚举属性的字符串数组。比如:传入字符串,返回索引;传入对象,返回属性名。
这种方法的调用也比较特殊:
<script src="ajax.js"></script>
<script>
let promise=$ajax({methods:'GET',url:'xxx'});
promise.then(function(res){
console.log(res); //完成
},function(err){
console.log(err); //异常
});
</script>
希望文章能够对大家的学习和工作产生帮助!哈哈