一、ajax基础
ajax概述
浏览器提供的一套方法,可以实现页面无刷新更新数据
Ajax应用场景
1、页面上拉加载更多数据
2、列表数据无刷新分页
3、表单离开焦点表单验证
4、搜索框提示文字下拉列表
Ajax运行原理及实现
Ajax的实现步骤
1、创建ajax对象
var xhr = new XMLHttpRequest();
2、告诉Ajax请求地址以及请求方式
xhr.open('get','http://www.example.com');
3、发送请求
xhr.send();
4、获取服务器端与客户端的响应数据
xhr.onload = function (){
console.log (xhr.responseText);
}
请求方式传递
GET请求方式
xhr.open('get','http:www.example.com?name=zhangsan&age=20');
POST请求方式
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('name=zhangsan&age=20');
请求参数的格式
1.application/x-www-form-urlencoded
name=zhangsan&age=男
2.application/json
{name:'zhangsan',age:'20',sex:'男'}
在请求头中指定Content-Type属性的值是application/json,告诉服务器端当前请求参数的格式是json
JSON.stringify()//讲json对象转换成json字符串
注意:get请求是不能提交json对象数据格式的,传统网站表单提交也是不支持json对象数据格式的。
获取服务器端的相应
Ajax状态码
在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过成每一个步骤都会对应一个数值,这个数值就是ajax状态码
0:请求未初始化(还没调用open())
1:请求已经建立,但是还没有发送(还没有调用send())
2:请求已经发送
3:请求正在处理中,响应中有部分数据可以用了
4:相应已经完成,可以获取并使用服务器的响应了
xhr.readyState//获取 Ajax状态码
onreadystatechange 事件当Ajax状态码变化时将自动触发该事件
两种获取方式
1.onload事件
var xhr = new XMLHttpRequest();
xhr.open('get', 'dome1.php')
xhr.send();
xhr.onload = function () {
}
2onreadystatechange事件
var xhr = new XMLHttpRequest();
xhr.open('get','http//localhost:3000/readystate')
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
}
}
xhr.send();
两种获取服务器端相应的区别
| 区别描述 | onload事件 | onreadystatechange事件 |
|---|---|---|
| 是否兼容IE低版本 | 不兼容 | 兼容 |
| 是否需要判断Ajax状态码 | 不需要 | 需要 |
| 被调用次数 | 一次 | 多次 |
如果不需要兼容建议使用onload事件,代码更简单,并且只会调用一次
Ajax错误处理
1、网络畅通,服务器端能接收到请求,服务器端返回的 结果不是预期结果。
可以判断服务器返回的状态码,分别进行处理xhr.status获取的状态码
2、网络畅通,服务器端没有收到请求,返回404状态码
检查请求地址是否错误
3、网络畅通,服务器端能接收到请求,服务器端返回500状态码
服务器端错误,找后端程序员进行沟通
4、网络中断,请求无法发送到服务器
会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理*
xhr.onload = function(){
//当网络中断会触发onerror事件
xhr.onerror = function(){
alert('网络中断,无法发送Ajax请求');
}
}
//Ajax状态码:表示Ajax请求过程状态 是ajax对象返回的
//Http状态码:表示请求的处理结果 是服务器端返回的
低版本IE浏览器的缓存问题
问题:在低版本的IE浏览器中,在请求地址不发生改变的情况下,只有第一次请求才会发送给服务器,后续都会从浏览器的缓存中获取结果,即使服务器端的 数据更新了,服务器依然拿到的是缓存中的旧数据。
解决方案:在请求的后面请求参数,保证每一次请求的值不相同
xhr.open('get','http://www.example.com?t='+Math.random());
二、Ajax异步编程
同步异步概述
同步:一个人 同一时间只能做一个事情,只有一个事情做哇才能做另一件事情
异步:一个人一件事情做了一半,转而去做其他事情,再回头继续做其他未完成的事情
落实到代码上,就是落实到代码上,就是异步代码虽然需要花费时间去执行,但程序不会等待异步代码执行完成后再继续执行后续代码,而是直接执行后续代码当后续代码执行完成后再回头看异步代码是否返回结果,如己有返回结果,再调用事先准备好的回调函数处理异步代码执行的结果。
console.log('before');
setTimeout(
() =>{ console.log('last');
},2000);
console.log('after');
Ajax封装
问题:发送一次请求过多,发送多i请求代码冗余且重复。
解决方案:将请求代码封装到函数中,发送请求时调用函数即可。
ajax({
type:'get',
url:'http://www.example.com',
success: function (date) {
console.log(date);
}
})
例子1
function ajax (options) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//配置ajax对象
xhr.open(options.type,option.url);
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function () {
options.success(xhr.responseText);
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
success: function (date) {
console.log('这里是success函数' + date);
}
})
拓展:
再发送请求的时候向服务器传递参数:
请求番薯要考虑的问题
1.请求参数位置的问题
将请求参数传递到ajax函数内部,在函数内部根据请求方式的不同将请求参数放置在不同的位置 get放在请求地址的后面 post放在send方法中
2.请求参数格式的问题
application/ x -WWW- form- urlencoded 参数名称=参数值&参数名称=参数值 name=zhangsan&age=20 application/ json {name:' zhangsan', age: 20}
如果传递的是第一种类型很有可能需要将它转换成第二种,如果是第二种,很有可能需要转换成第一种,显然第二种转换成第一种更为方便
1.传递对象数据类型对于函数的调用者更加友好 2.在函数内部对象数据类型转换为字符串数据类型更加方便
例子2
function ajax (options) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//拼接请求参数的变量
var params = '';
for(var attr in options.data) {
//将参数转换成字符串格式
params += attr + '=' +options.data[attr] + '&';//因为attr是一个变量,对象后面不能直接.变量,所以用options.data[attr]
}
//将参数后面的&截取掉
//将截取的结果重新赋值给params
parms = params.substr(0,params.length-1);
//判断请求方式
if (potions.type == 'get'){
options.url = options.url + '?' +params;
}
//配置ajax对象
xhr.open(options.type,option.url);
if (options.type == 'post') {
//设置请求参数格式的类型
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(params);
}
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function () {
options.success(xhr.responseText);
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
data: {
name: 'zhangsan',
age: 20
},
success: function (data) {
console.log('这里是success函数' + date);
}
})
完善:
如果传递参数的人传递json
例子3
function ajax (options) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//拼接请求参数的变量
var params = '';
for(var attr in options.data) {
//将参数转换成字符串格式
params += attr + '=' +options.data[attr] + '&';//因为attr是一个变量,对象后面不能直接.变量,所以用options.data[attr]
}
//将参数后面的&截取掉
//将截取的结果重新赋值给params
parms = params.substr(0,params.length-1);
//判断请求方式
if (potions.type == 'get'){
options.url = options.url + '?' +params;
}
//配置ajax对象
xhr.open(options.type,option.url);
if (options.type == 'post') {
//用户希望向服务器传递的请求参数的类型
var contentType = options.header['Content-Type']//因为带了-,所以必须是字符串不然不合法,用了options.header['Content-type']
//设置请求参数格式的类型
xhr.setRequestHeader('Content-Type','contentType');
//判断用户希望的请求参数格式的类型
//如果类型为json
if (contentType == 'application/json'){
//向服务器端传递json数据格式的参数
xhr.send(JSON.striongify(oprions.data));
}else {
//向服务器端传递普通类型的请求参数
xhr.send(params)
}
xhr.send(params);
}
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function () {
options.success(xhr.responseText);
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
data: {
name: 'zhangsan',
age: 20
},
header:
success: function (data) {
console.log('这里是success函数' + date);
}
})
完善:
服务器响应成功与失败分离:
function ajax (options) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//拼接请求参数的变量
var params = '';
for(var attr in options.data) {
//将参数转换成字符串格式
params += attr + '=' +options.data[attr] + '&';//因为attr是一个变量,对象后面不能直接.变量,所以用options.data[attr]
}
//将参数后面的&截取掉
//将截取的结果重新赋值给params
parms = params.substr(0,params.length-1);
//判断请求方式
if (potions.type == 'get'){
options.url = options.url + '?' +params;
}
//配置ajax对象
xhr.open(options.type,option.url);
if (options.type == 'post') {
//用户希望向服务器传递的请求参数的类型
var contentType = options.header['Content-Type']//因为带了-,所以必须是字符串不然不合法,用了options.header['Content-type']
//设置请求参数格式的类型
xhr.setRequestHeader('Content-Type','contentType');
//判断用户希望的请求参数格式的类型
//如果类型为json
if (contentType == 'application/json'){
//向服务器端传递json数据格式的参数
xhr.send(JSON.striongify(oprions.data));
}else {
//向服务器端传递普通类型的请求参数
xhr.send(params)
}
xhr.send(params);
}
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function () {
//当http状态码等于200的时候
if (xhr.status == 200) {
//请求成功 调用处理成功情况的函数
options.success(xhr.responseText, xhr);
}else {
//请求失败 调用处理失败情况的函数
options.error(xhr.responseText, xhr);
}
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
data: {
name: 'zhangsan',
age: 20
},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function (data,xhr) {
console.log('这里是success函数' + data);
}
error: function (data,xhr){
console.log('这里是error函数' + data);
}
})
完善:
将json字符串转换成json对象
function ajax (options) {
//创建ajax对象
var xhr = new XMLHttpRequest();
//拼接请求参数的变量
var params = '';
for(var attr in options.data) {
//将参数转换成字符串格式
params += attr + '=' +options.data[attr] + '&';//因为attr是一个变量,对象后面不能直接.变量,所以用options.data[attr]
}
//将参数后面的&截取掉
//将截取的结果重新赋值给params
parms = params.substr(0,params.length-1);
//判断请求方式
if (potions.type == 'get'){
options.url = options.url + '?' +params;
}
//配置ajax对象
xhr.open(options.type,option.url);
if (options.type == 'post') {
//用户希望向服务器传递的请求参数的类型
var contentType = options.header['Content-Type']//因为带了-,所以必须是字符串不然不合法,用了options.header['Content-type']
//设置请求参数格式的类型
xhr.setRequestHeader('Content-Type','contentType');
//判断用户希望的请求参数格式的类型
//如果类型为json
if (contentType == 'application/json'){
//向服务器端传递json数据格式的参数
xhr.send(JSON.striongify(oprions.data));
}else {
//向服务器端传递普通类型的请求参数
xhr.send(params)
}
xhr.send(params);
}
//发送请求
xhr.send();
//监听xhr对象下面的onload事件
//当xhr对象接收完响应数据后触发
xhr.onload = function () {
//获取响应头中的数据
var contentType = xhr.getResponseHeader('Content-Type');
//服务器端返回的数据
var responseText = xhr.responseText;
//如果响应类型中包含application/json
if (contentType.includes(application/json)) {
//将json字符串转换成json对象
responseText = JSON.parse(resonseText);
}
//当http状态码等于200的时候
if (xhr.status == 200) {
//请求成功 调用处理成功情况的函数
options.success(responseText, xhr);
}else {
//请求失败 调用处理失败情况的函数
options.error(responseText, xhr);
}
}
}
ajax({
//请求方式
type:'get',
//请求地址
url:'http://localhost:3000/first',
data: {
name: 'zhangsan',
age: 20
},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},