1.ajax网络请求
1.1ajax发送get请求:请求参数必须拼接在url地址的后面
封装函数:
<script>
//对象转查询字符串
function objToSearchString(obj){
var str = ''
for(var key in obj){
str += `${key}=${obj[key]}&`;
}
return str.slice(0,str.length-1);
}
//封装ajax函数
function ajax( method, url, params , cb ){
//1.创建请求对象
var xhr = new XMLHttpRequest()
//2.配置请求对象
xhr.open(method,url+"?"+objToSearchString(params));
//3.设置回调函数
xhr.onreadystatechange = function(){
if( xhr.readyState == 4 ){
cb( JSON.parse(xhr.responseText) )
}
}
//4.发送请求
xhr.send();
}
ajax('get','https://xxx',{page:1,count:5},function(data){
console.log(data);
});
</script>
ajax发送post请求,必须在发送请求前设置content-type请求头::
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
请求参数必须放在请求体中
<script>
//对象转查询字符串
function objToSearchString(obj){
var str = ''
for(var key in obj){
str += `${key}=${obj[key]}&`;
}
return str.slice(0,str.length-1);
}
//封装ajax函数
function ajax( method, url, params , cb ){
//1.创建请求对象
var xhr = new XMLHttpRequest()
//2.配置请求对象
xhr.open(method,url);
//3.设置回调函数
xhr.onreadystatechange = function(){
if( xhr.readyState == 4 ){
cb( JSON.parse(xhr.responseText) )
}
}
//4.发送请求
//先对post请求设置 content-type 请求头
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send( objToSearchString(params) );
}
ajax('post','https://xxx',{page:1,count:5},function(data){
console.log(data);
});
</script>
1.3 get和post的区别
1)携带参数方式的不同:get通过cookie,url携带参数,而post 将数据存储在body内。
2)携带的数据量不同:get的url会有长度的限制,携带的数据量非常有限,而post携带的数据量可以非常大。
3)数据的安全性:post比get安全,因为post的数据在地址栏上不可见。
4)请求参数的类型:get请求,拼接在url地址后面的参数只能是文本字符. post请求, 携带的参数可以是文本字符, 也可以是二进制数据( 图片,音视频, 压缩包 )
1.4对ajax的重新封装
我们可以通过if判断语句对ajax重新封装,使其可以根据请求类型的不同, 自动选择请求的方式。
//对象转查询字符串
function objToSearchString(obj){
var str = ''
for(var key in obj){
str += `${key}=${obj[key]}&`;
}
return str.slice(0,str.length-1);
}
//封装ajax函数
function ajax( method, url, params , cb ){
//1.创建请求对象
var xhr = new XMLHttpRequest()
//2.配置请求对象
xhr.open(method, method == 'get' ? url + "?" + objToSearchString(params) : url );
//3.设置回调函数
xhr.onreadystatechange = function(){
if( xhr.readyState == 4 ){
cb( JSON.parse(xhr.responseText) )
}
}
//4.发送请求
//先对post请求设置 content-type 请求头
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send( method == 'get' ? null : objToSearchString(params) );
}
2.promise
需求: 先发请求获取用户信息(用户id,用户头像,用户昵称), 再发请求获取用户的考试成绩( 用户id,用户成绩,平均成绩 ), 再发请求获取近三个月的考试成绩.
知识点: 所有ajax请求的回调函数都是异步执行的.
如果后一个请求依赖于前一个请求的结果, 这样嵌套的ajax调用就产生 "回调地狱" 现象.
可以使用promise技术来解决这个问题 ( 回调地狱 )
promise本身是es6的新语法, 意思是"承诺"
promise以三种状态来表示内部代码运行的结果.
状态: unfinished 未完成(初始状态)
状态一 : finished 完成,成功
状态二 : rejected 拒绝,失败
语法: new Promise( (resolve,reject)=>{} )
new Promise( ( resolve,reject )=>{
//这里可以写任何js代码
//写在这里的代码可以看做一个任务, 一个承诺, 一个耗时的功能, 这个任务最终必须有一个运行结果( 必须是明确的结果 )
//想要在这里更改Promise对象的状态, 必须使用resolve,reject函数
//调用resolve函数 则Promise对象的状态会立即变为 finished 成功
//调用reject函数 则Promise对象的状态会立即变为 rejected 失败
//用定时器模拟一个耗时任务,5s后任务执行完毕
setTimeout(()=>{
resolve(888888); //当前Promise对象的状态变为 finished 成功,会立即调用then方法的回调函数.
//reject(888888); //将当前Promise对象的状态变为 rejected 失败,会立即调用catch方法的回调函数.
},5000)
}).then((res)=>{
console.log("Promise对象的状态变为 finished 成功",res);
}).catch((err)=>{
console.log("Promise对象的状态变为 rejected 失败",err);
})
promise重新封装ajax函数(避免回调地狱)
var p = new Promise( ( resolve,reject )=>{
setTimeout(()=>{
//resolve(888888); //当前Promise对象的状态变为 finished 成功,会立即调用then方法的回调函数.
reject(888888); //将当前Promise对象的状态变为 rejected 失败,会立即调用catch方法的回调函数.
},5000)
})
//当Promise对象的状态变为 finished 成功时, 会立即执行then和finally的回调
//当Promise对象的状态变为 rejected 失败时, 会立即执行catch和finally的回调
//不论最终Promise对象的状态是 finished 还是 rejected , finally的回调都会执行
p.then((res)=>{
console.log("Promise对象的状态变为 finished 成功",res);
}).catch((err)=>{
console.log("Promise对象的状态变为 rejected 失败",err);
}).finally(()=>{
console.log("Promise对象的状态终止(结束)");
})
function ajax( time ){
return new Promise((resolve,reject)=>{
//用定时器模拟一个耗时任务
setTimeout(()=>{
resolve();
},time)
//也可以在这里发送网络请求
})
}
//Promise.all( [] ).then( ()=>{} )
//参数一: 包裹多个Promise对象的数组,
//参数二: 只有在参数一中的所有Promise对象都有了确定的结果 才执行的回调函数.
//应用: 同时并发多个请求(ajax)
Promise.all([ ajax(1000),ajax(3000),ajax(5000),ajax(2000) ]).then(()=>{
console.log('所有任务都完成');
})
//Promise.race( [] ).then( ()=>{} )
//参数一: 包裹多个Promise对象的数组,
//参数二: 只有在参数一中的所有Promise对象都有了确定的结果 才执行的回调函数.
Promise.race([ ajax(1000),ajax(3000),ajax(5000),ajax(2000) ]).then(()=>{
console.log('已经有一个任务完成,但是剩余任务可能还没有完成');
})
try catch可以检测错误,将错误代码放入try中,后面的代码可以继续执行
//try 代码块中写可能出错的代码
//catch 代码块用来捕获错误,并处理错误
//try catch 的作用: 将可能出错的代码包裹在try代码块中, 避免try catch之后的代码因为try中的错误而导致无法执行
try {
var num = null;
num.name = '李煜';
console.log( num.name );
} catch (error) {
console.log(error);
}
console.log('这是try catch后面的代码,即使是try中的代码报错,这里的代码依然会执行');