9.9 ajax的请求和封装
AJAX实现步骤
想要实现ajax需要四个步骤
-
创建xhr[XmlHttpRequest]对象
-
配置请求信息
-
发送请求
-
判断请求是否发送成功
Ajax实现过程
- 初始化XMLHttpRequest对象
if (window.XMLHttpRequest) {// Mozilla, Safari, ...var http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 5 ,6var http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
- XMLHttpRequest发出HTTP请求
http_request.open("GET|POST","test.php?username=jack&age=18"+,false);
http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //仅POST请求时需要设置
http_request.send("username=jack&age=18");
- XMLHttpRequest取得响应数据并显示
http_request.onreadystatechange = function(){if(http_request.readyState==4 && http_request.status==200){$("div").text(http_request.responseText)}
}
属性解析:
readyState
属性存留 XMLHttpRequest 的状态。
onreadystatechange
属性定义当 readyState 发生变化时执行的函数。
status
属性和 statusText
属性存有 XMLHttpRequest 对象的状态。
属性 | 描述 |
onreadystatechange | 定义了当 readyState 属性发生改变时所调用的函数。 |
readyState | 保存了 XMLHttpRequest 的状态。 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 正在处理请求 4: 请求已完成且响应已就绪 |
status | 200: “OK” 403: “Forbidden” 404: "Page not found"如需完整列表,请访问 Http 消息参考 |
statusText | 返回状态文本(例如 “OK” 或 “Not Found”) |
案例:注册账号,向php请求数据,并返回请求内容
html页面
注册:<input type="text" name="tel" placeholder="请使用电话号码进行注册"><span></span>
<script>
var oInp=document.getElementsByTagName('input')[0];
var oSpan=oInp.nextElementSibling;// 调用失去焦点事件
addEvent(oInp,'blur',getAjax);
function getAjax(){var data=oInp.value;// 通过正则判断数据格式是否是电话号码//步骤1:创建异步对象if (window.XMLHttpRequest) {// Mozilla, Safari, ...var http_request = new XMLHttpRequest();} else if (window.ActiveXObject) { // IE 5 ,6var http_request = new ActiveXObject("Microsoft.XMLHTTP");}var data='username='+$(this).val();//步骤2:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端http_request.open("GET","test.php?"+data,false);http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //仅POST请求时需要设置//步骤3:发送请求http_request.send();//步骤4:如果能够进入到这个判断,说明数据完美的返回回来了,并且请求的页面是存在的if(http_request.readyState==4 && http_request.status==200){$("span").text(http_request.responseText)// 请求成功了,需要php判断电话号码,是否存在if(Number(http_request.responseText)){oSpan.innerHTML='可以使用当前电话号码';}else{oSpan.innerHTML='电话号码已经存在';}}else{$("span").text('ERROR')}
}
</script>
php文件内容
<?php// 1.接收数据$tel=$_GET['tel'];// 2.判断数据,13409370012 18336396807if($tel=='18336396807' || $tel=='13409370012'){echo(0);// 电话号码已经存在}else{echo(1); //可以使用当前电话号码}// 3.返回数据// 获取前端post请求传递过来的数据
?>
案例:ajax请求数据,请求回来的数据格式为字符串
Json.php文件
echo '{"result_code": 200,"result_msg": "OK","result_list": [{"patientName": "刘德华","age": 60,"sex": "男","departmentname": "骨科","Inspectionitems": "血糖,甲状腺,心肺,肾脏"},{"patientName": "马德华","age": 70,"sex": "男","departmentname": "猪八戒","Inspectionitems": "血糖,甲状腺,心肺,肾脏"},{"patientName": "唐僧","age": 60,"sex": "男","departmentname": "骨科","Inspectionitems": "血糖,甲状腺,心肺,肾脏"}]
}';
html文件
<style>input{width: 300px;height: 30px;}
</style>
<script src='js/tools.js'></script>
<script>
addEvent(window,'load',getAjax);
function getAjax(){// 1. 创建ajax对象if(window.XMLHttpRequest){var http_request=new XMLHttpRequest();}else{var http_request=new ActiveXObject('Microsoft.XMLHTTP');}// 2. 配置请求内容,发送请求http_request.open('GET','json.php',false);http_request.send();// 3. 判断 请求有没有完成,返回应答的内容if(http_request.status==200 && http_request.readyState==4){//json字符串的格式console.log(http_request.responseText);// json字符串---json// 循环输出// html创建表格}else{console.log('请求失败!');}
}
</script>
注意:通过responseText获取到的数据是字符串的格式,但是里面的结构跟json或者数组是一样的; 所以,我们需要把这个json格式的字符串,专为真正的json
JSON 格式转换
-
Javascript Object Notation,是一种轻量级的数据交换格式
-
JSON支持多种语言
-
注意:json格式中键必须用 “” 包括起来,而且必须是双引号
-
格式
{key:value,key:value,.....} 对象格式
[{key:value,key:value,.....},{key:value,key:value,.....},......] 数组格式
- PHP处理:
$json=json_encode($array)
$array=json_decode($json)
- JavaScript处理:
eval( '('+json+')' )
JSON.parse(json) json字符串转为json
JSON.stringify() json转为json字符串
请求cnode接口中的数据
地址:https://cnodejs.org/api/v1/topics?tab=ask
需求:请求cnode官网的数据,返回数据后,按照cnode官网的格式进行显示
<style>body{background-color: #ccc;}body,p,h1,ul,li{margin:0;padding: 0;}li{list-style: none;}a{color: #000;text-decoration: none;}.warp{width: 800px;margin: 0 auto;background-color: azure;border-radius: 5px;}.tab{}.tab ul{overflow: hidden;}.tab ul li{float: left;padding: 3px 7px;border-radius: 3px;background-color: #fff;color: #80bd01;margin: 10px 15px;}.tab .active{background-color: #80bd01;color: #fff;}.item{border-bottom: 1px solid #f0f0f0;padding: 10px;line-height: 30px;width: 95%;overflow: hidden;}.item img{width: 30px;height: 30px;float: left;}.count{color: #b4b4b4;font-size: 10px;float: left;margin: 0 10px;}.count-big{font-size: 16px;color: #9e78c0;}.goods{background-color: #80bd01;color: #fff;padding: 0px 3px;border-radius: 2px;float: left;margin: 0 5px;}.item a{color: #333;white-space: nowrap;display: inline-block;vertical-align: middle;float: left;}.time{float: right;font-size: 10px;color: #b4b4b4;}
</style>
<body><div class="warp"><div class="tab"><ul><li class="active">全部</li><li>精华</li><li>分享</li><li>问答</li></ul></div><div class="list"></div></div>
</body>
<script>var list = document.querySelector('.list');window.onload = function(){if(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else if(window.ActiveXObject){var xhr = new ActiveXObject("Microsoft.XMLHTTP");}// xhr.open('get','cnode.php',false); 请求本地数据xhr.open('get','https://cnodejs.org/api/v1/topics',false); // 请求cnode接口数据xhr.send();if(xhr.readyState == 4 && xhr.status == 200){var getMsg = JSON.parse(xhr.responseText).data;console.log(getMsg);for(var i=0;i<getMsg.length;i++){getMsg[i]['top'] = getMsg[i]['top']?'置顶':''list.innerHTML += '<div class="item"><img src="'+getMsg[i].author['avatar_url']+'" alt=""><span class="count"><span class="count-big">'+getMsg[i]['reply_count']+'/</span>'+getMsg[i]['visit_count']+'</span><span class="goods">'+ getMsg[i]['top'] +'</span><a href="#"> '+getMsg[i]['title']+'</a><span class="time">一天前</span></div>';}}}
</script>
Ajax的封装
封装ajax(get,post)同步请求和异步请求
注意:一般情况下,请求方式和是否为异作为参数值传递到函数中,但是在jquery的封装中并没有把他们作为参数值传递,所以咱们在封装的时候也不要把请求方式和是否为异步作为参数值传递;
只是把请求路径,参数,成功的回调函数,失败的回调函数,作为参数值传递
分别封装
ajax-get同步请求
ajax-get异步请求
ajax-post同步请求
ajax-post异步请求 四个请求,可参考文档
1)get 同步请求
/*
get 同步 getSync
参数:urls 路径parms 参数sucFun()errorFun()
*/
function getSync(urls,parms,sucFun,errorFun){//1. 获取xhrif(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else{var xhr = new ActiveXObject('Microsoft.XMLHTTP');}// 2. 配置请求信息xhr.open('get',urls+'?'+parms,false);// 3. 发送请求xhr.send(null);// 4. 接受信息if(xhr.readyState == 4){if(xhr.status==200){sucFun(xhr);}else{errorFun();}}
}
2)get异步请求 注意:在异步封装的时候,需要使用onreadystatechange来监听readystate状态的改变,只要onreadystatechange发生改变,就能触发对应的方法,这时候就能对异步请求的数据进行检测
/*
get 异步 getAsyn
参数:urls 路径parms 参数sucFun()errorFun()
*/
function getAsyn(urls,parms,sucFun,errorFun){//1. 获取xhrif(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else{var xhr = new ActiveXObject('Microsoft.XMLHTTP');}// 2. 配置请求信息xhr.open('get',urls+'?'+parms,true);// 3. 发送请求xhr.send(null);// 4. 接受信息xhr.onreadystatechange = function (){if(xhr.readyState == 4){if(xhr.status==200){sucFun(xhr);}else{errorFun();}}}}
3)post同步请求
/*
post 同步 postSync
参数:urls 路径parms 参数sucFun()errorFun()
*/
function postSync(urls,parms,sucFun,errorFun){//1. 获取xhrif(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else{var xhr = new ActiveXObject('Microsoft.XMLHTTP');}// 2. 配置请求信息xhr.open('post',urls,false);// 3. 发送请求xhr.send(parms);// 4. 接受信息if(xhr.readyState == 4){if(xhr.status==200){sucFun(xhr);}else{errorFun();}}
}
4)post异步请求
/*
post 异步 postAsyn
参数:urls 路径parms 参数sucFun()errorFun()
*/
function postAsyn(urls,parms,sucFun,errorFun){//1. 获取xhrif(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else{var xhr = new ActiveXObject('Microsoft.XMLHTTP');}// 2. 配置请求信息xhr.open('post',urls,true);// 3. 发送请求xhr.send(parms);// 4. 接受信息xhr.onreadystatechange = function (){if(xhr.readyState == 4){if(xhr.status==200){sucFun(xhr);}else{errorFun();}}}
}
调用封装并渲染数据
案例:调用封装,调用get异步封装,完成数据渲染 html
<style>
#patientTab {width: 800px;margin: auto;border-collapse: collapse;
}
</style>
<table id="patientTab" border="1"><tr><th>患者姓名</th><th>年龄</th><th>性别</th><th>部门</th><th>检查项目</th></tr>
</table>
js
var urlStr = "http://192.168.64.2/AJAX-1/ryh.php";
// get 异步索要数据
ajaxGetAsync(urlStr, "", function(res) {// 返回的是json字符串console.log(res.responseText);// json 解析var jsonObj = JSON.parse(res.responseText);console.log(jsonObj);var relArr = jsonObj.result_list;// 页面渲染(修改DOM)for (var i = 0; i < relArr.length; i++) {var trM = document.createElement("tr");var patObj = relArr[i];for (var k in patObj) {var tdM = document.createElement("td");tdM.innerHTML = patObj[k];trM.appendChild(tdM);}$("#patientTab")[0].appendChild(trM);}}, function() {alert("请求失败");
});
什么是接口,接口文档?
接口文档编辑器:https://www.showdoc.com.cn/item/index
使用ajax请求实现懒加载
什么是懒加载:
懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。
懒加载的优点:
-
提升用户体验,加快首屏渲染速度
-
减少无效资源的加载
-
防止并发加载的资源过多会阻塞 js 的加载
懒加载的原理:
首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在 data-original 属性中,当页面滚动的时候需要去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内则将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。
实现代码:
<style>.goods{width: 300px;height: 200px;border: 1px solid #f00;}img{width: 100px;}
</style>
<script src="./xiaomi-data.js"></script>
<div id="content"></div>
<script>var miData = data.data;var str = '';var cont = document.getElementById('content');function loadInitData(){for(var i=0;i<miData.length;i++){str += `<div class="goods"><img src="./img-placeholder.png" alt="" data-src="${miData[i].info.image}"> <div>价格:${miData[i].info.price}</div> <div>销量:${miData[i].info.comments}</div> <div>${miData[i].info.name}</div> </div>`;}cont.innerHTML += str;}// 页面初始化时,判断图片的加载时机function loadImg(){var imgList = cont.getElementsByTagName('img');var top;// 页面的高度var winHeight = document.documentElement.clientHeight;for(var i=0;i < imgList.length;i++){// 获取图片距离页面顶端的偏移值top = imgList[i].offsetTop;if(top <= winHeight){// 加载图片:把data-src中的数据放在src中console.log('加载第一幅图片',top,winHeight);imgList[i].src = imgList[i].dataset.src;}}}function onScroll(){window.onscroll = function(){var scrollTop = document.documentElement.scrollTop;var winHeight = document.documentElement.clientHeight;var imgList = cont.getElementsByTagName('img');var top;// 页面的高度var winHeight = document.documentElement.clientHeight;for(var i=0;i < imgList.length;i++){// 获取图片距离页面顶端的偏移值top = imgList[i].offsetTop;if(winHeight + scrollTop >= top){imgList[i].src = imgList[i].dataset.src;}}}}loadInitData();loadImg()onScroll()
</script>
官网地址: https://m.lrts.me/ 编写懒人听书移动端首页及跳转详情
首页数据接口地址:https://m.lrts.me/ajax/getHomePage
详情页数据接口地址:https://m.lrts.me/ajax/getBookDetail?bookId=43072454
cnode接口:https://cnodejs.org/