关于Ajax,看了网上很多教程和博客之类的,感觉整理的知识点都大同小异,真正用上的一些细节反而很难找,于是自己整理了一份自用版ajax教程,可能一些功能性的语句还无法熟练使用,此教程参考了阮一峰老师的教程和黑马某位老师的b站视频,具体链接在文末会po出。
一、应用场景
1、页面上拉加载更多数据
2、列表数据无刷新分页
3、表单项离开焦点数据验证
4、搜索框提示文字下拉列表
二、实现步骤
1、创建Ajax对象
XMLHttpRequest本身是一个构造函数,可以使用new命令生成实例。
var xhr =new XMLHttpRequest();
若要向服务器传递请求参数?
GET(请求参数放在地址后面)
①获取表单文本框的值
若为表单,input中value属性存储用户在文本框中输入值。
②将其拼接成请求参数的格式,
(参数名称=参数值&参数名称=参数值)
var params = 'username='+ nameValue +'&age=' +ageValue;
③将拼接好的参数放在请求地址的后面
‘地址?’+ 请求参数(可将其赋给一个变量)
xhr.open('get','http://47.95.214.19:8081/center?'+params);
POST
(要点:请求参数放在send(请求体)中、必须在请求发送前设置请求参数类型。)
①设置头信息setRequestHeader,包含
Content-Type属性 及其对应的值
请求参数格式类型(Content-Type的值)判断?
若参数名称=参数值&参数名称=参数值
则值为
application/x-www-form-urlencoded
具体写法如下
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
若为JSON对象({name= ‘zhangsan’,age=20})
则值为
application/json
xhr.setRequestHeader('Content-Type','application/json');
2、配置Ajax对象(open方法告诉请求地址和请求参数)
3、发送请求
xhr.send()方法用于实际发出 HTTP 请求,它的参数是可选的。
如果不带参数,就表示 HTTP 请求只有一个 URL,没有数据体,典型例子就是 GET 请求;
xhr.send();
如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。
若用post请求传递参数名称=参数值&参数名称=参数值 时
直接将参数放在send()中
send('username='+ nameValue +'&age=' +ageValue);
若用post请求传递json对象时,需要将json对象转化为json字符串再放入send中。
如何将json对象转化为json字符串?
JSON.stringify:将json对象转化为json字符串
xhr.send(JSON.stringify({name:'lisi' ,age:50}));
(可以设置变量来储存参数)
4、获取服务器端响应数据
①监听请求是否完成:
onload事件:事件(请求成功完成)的监听函数。 (对象接收完响应数据)
onreadystatechange属性:指向一个监听函数。readystatechange事件发生时(实例的readyState属性变化),就会执行这个属性。
②接收数据:
responseText属性返回从服务器接收到的JSON字符串,我们需要将它转化为JSON对象。
如何将json字符串转化为json对象?
JSON.parse()
拼接数据:将JSON对象与html进行拼接,再展示响应数据。
使用DOM方法将拼接好的字符串追加到页面
xhr.onload=function () {
console.log(xhr.responseText);
//将JSON字符串转化为JSON对象
var responseText = JSON.parse(xhr.responseText)
var str = '<h2>'+ responseText.name +'</h2>';
document.body.innerHTML = str;
}
也可用es6的模板字符串来拼接
var str = `
<h2>${responseText.name}</h2>
`;
注:
1、参数必须以字符串的形式进行传递,所以用post方法传递json对象时,客户端必须将json对象转化为json字符串传给服务器。获取服务器端响应数据时,需将json字符串转化为json对象.
(get请求和传统网站的表单不支持json对象数据格式)
2、状态码
Ajax状态码:Ajax请求的过程对象,是ajax对象返回的。(判断请求是否完成)
readyState返回一个整数,表示实例对象的当前状态。该属性只读。它可能返回以下值。
0,表示 XMLHttpRequest 实例已经生成,但是实例的open()方法还没有被调用。
1,表示open()方法已经调用,但是实例的send()方法还没有调用,仍然可以使用实例的setRequestHeader()方法,设定 HTTP 请求的头信息。
2,表示实例的send()方法已经调用,并且服务器返回的头信息和状态码已经收到。
3,表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的responseType属性等于text或者空字符串,responseText属性就会包含已经收到的部分信息。
4,表示服务器返回的数据已经完全接收,或者本次接收已经失败。
onreadystatechange属性指向一个监听函数。readystatechange事件发生时(实例的readyState属性变化),就会执行这个属性。
Http状态码:请求的处理结果,是服务器端返回的。(判断请求是否处理成功)
status属性储存http状态码
200, OK,访问正常
301, Moved Permanently,永久移动
302, Move temporarily,暂时移动
304, Not Modified,未修改
307, Temporary Redirect,暂时重定向
401, Unauthorized,未授权
403, Forbidden,禁止访问
404, Not Found,未发现指定网址(请求地址/方式错误)
500, Internal Server Error,服务器发生错误
onload和onreadystatechange都可以判断请求是否完成,下面一张图表现了区别,一般用onload方法。无论都哪种方法,都要用xhr.status来判断请求是否成功。
//请求完成,触发onload事件
xhr.onload = function () {
//请求成功,调用处理成功情况的函数
if(xhr.status ===200){
defaults.success(responseText,xhr);
}else{
defaults.error(responseText,xhr);
}
}
xhr.onreadystatechange = function () {
if (this.status === 200 && this.readyState === 4) {
defaults.success(responseText,xhr);
}else{
defaults.error(responseText,xhr);
}
}
3、网络中断时无法触发onload事件,可以触发onerror事件。
4、低版本IE浏览器的缓存问题
在低版本IE中,若请求地址不变,只有第一次向服务器端发送请求,后续的请求都会从浏览器的缓存中获取结果,即使服务器更新客户端拿到的也只是缓存的旧数据。
方法:在请求地址后加请求参数,保证每次请求参数的值不同。(参数不能和拼接的value值相同)
Math.random():生成一个冲0-1间的随机小数。
xhr.open('get','http://47.95.214.19:8081/center?t'+Math.random());
Ajax封装
可用于发送多次请求
函数参数(即每个ajax请求的不同点):请求方式、请求地址、请求参数、返回结果的处理,因此可以传递一个对象作为函数参数。
返回结果的处理中,将onload触发后返回的请求结果(responseText)传入success函数中,对请求结果进行处理。
请求参数需考虑两点,
1、根据请求方式的不同将请求参数放入不同的位置(get拼接在地址后,post放在send里面)。
2、根据Content-Type不同传入不同类型的参数,但是由于在函数内对象转字符串更容易,所以统一传入对象,若有需要可在函数内将其手动转为字符串。
函数内部对象转化为字符串?
循环对象(var in)
//拼接请求参数的变量(字符串格式)
var params = '';
//循环用户传入的对象格式参数
for(var attr in defaults.data){
//将参数格式转化为字符串
params += attr + '=' + defaults.data[attr]+'&';
}
//将字符串最后&截去掉
params = params.substr(0,params.length-1);
attr为属性(名),属性值:options.data.[attr],因为attr是变量,所以不能直接加到对象后面。
‘Content-Type’属性含‘-’,若不是字符串(不加‘’),则不合法,所以表示其属性值:options.header[‘Contant-Type’]
3、Json字符串转化为json对象需要先判断
4、设置一些默认数据,减少参数。。。
还有一些封装的细节我就不一一赘述了,可以去看黑马的视频。
阮一峰ajax:
https://javascript.ruanyifeng.com/bom/ajax.html
黑马:
BV1ji4y1876Y