blog-ajax总结

1.什么是ajax?

简单理解是一种用于客户端(浏览器)与后台服务器进行异步交互(传递信息)的技术。

2.ajax的特点

不需要页面全局刷新就可以进行与后台的交互。

3.工作原理

ajax的异步请求过程:
1)浏览器通知XMLHttpRequest对象(简称XHR对象),让它去找服务器要数据用来显示给用户看
2)浏览器通知完毕后继续自己的任务
3)XHR对象接到通知后去找服务器,请求它给点数据
4)服务器经过一系列的翻找,将数据给回XHR对象
5)XHR对象拿着数据回来,并告诉浏览器已经拿到数据了
6)浏览器拿着数据去渲染显示出来

ajax的请求有同步和异步两种,下面举个通俗易懂的例子来介绍
异步请求:
假设现在处于古代战场上,连长带着一个连的人去打仗,前方战场突发了一些意外连长不知道该怎么解决,需要询问上级,连长(浏览器)就叫了一个通信兵(XHR对象),告诉它回去的线路、去找哪个上级、要带什么回来战场等信息(请求配置),将必要的信息告诉通信兵后,连长就继续去做别的任务了,通信兵带着信息回后方大本营找上级,告诉他前方发生的状况,上级经过一系列的讨论后得到解决方案(数据),上级将方案告诉给这个通信兵,让他带回前方战场,通信兵回到前方战场后将上级交代的告诉连长,连长就根据上级的指令处理这个意外。
同步请求:
同步请求与异步请求相类似,唯一不同的是,通信兵回去到带回指令的这一段时间内,连长(浏览器)什么也不做,只能干坐着等通信兵带回指令才能继续执行任务。这个期间浏览器就处于白屏等待阶段,用户不能点击页面。

4.使用XMLHttpRequest对象实现ajax异步交互(原生js)

XMLHttpRequest对象是浏览器的内置对象

// 1.实例化XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 设置响应返回的数据的格式(可选)
xhr.responseType = "json";
// 2.设置请求行  url是后台服务器的请求地址
xhr.open("post",url);
// 3.设置请求头
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 4.设置请求体
// data=“username=张三&password=123"
xhr.send(data);//data是请求的数据
// 5.监听响应
xhr.onreadystatechange = function(){
	// 判断响应的状态
	if(this.status === 200){
		//....业务逻辑处理
		var res = this.response;
	}else{
		// 响应失败获取不到数据的处理
	}
}

方法
open(method,url,asyncFlag)
用来设置请求行,method指定请求类型get或post等,url是请求的后台服务器接口地址,asyncFlag指定是异步请求(true)还是同步请求(false),默认为true异步请求

setRequestHeader()
设置请求头,application/x-www-form-urlencoded类型是指请求发送的数据编码为“key=value”

send()
设置请求体信息,当为post请求时用该方法发送数据

属性
onreadystatechange
指定当请求状态改变时触发的方法

status
http请求返回的状态码—200表示请求成功(成功获取数据);404表示请求文件未找到(请求地址写错);500表示后台服务器出错

response
请求返回的响应信息(包括需要的数据)

5.使用jQuery实现ajax异步交互

jQuery有封装好的ajax方法可直接调用请求数据

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>

$.ajax({
	url:"",//请求地址
	type:"post",//请求方式
	contentType:"application/x-www-form-urlencoded",//请求数据类型
	data:"",//请求数据
	dataType:"",//预期服务器返回的数据类型
	success:function(){
		// 请求成功的回调函数,可在这里拿到响应的数据
	},
	error:function(){
		// 请求失败的回调函数
	}
})

jQuery还有两个速写方法

$.get(url[,data][,success][,dataType])get方式请求
		url 	请求地址
		data  请求参数,对象
		success		回调函数
		dataType 	响应数据类型
//===>
$.get(url,{id:2},function(data,textStatus){
	console.log(data,textStatus);
})
$.post(url[,data][,success][,dataType])
	以post方式请求
		url 	请求地址
		data  请求参数,对象
		success		回调函数
		dataType 	响应数据类型
//==>
var data = {
	province:"甘肃省",
	city:"兰州市",
	area:"七里河",
	address:"人民路",
	telephone:"18891238901"
}
// content-type, querystring
$.post(url,data,function(response,status){
	console.log(response,status);
})

6.使用ES6的promise对象实现ajax

promise对象一共有三种状态,pending、resolved(成功)、rejected(失败),一旦promise对象的状态改变了之后,就不会再改变。所以我们可以利用这一特性封装异步操作,当异步请求成功后resolve回调函数就会执行,就可以通过then方法获取异步操作的响应信息,可以通过catch方法捕获请求失败的响应信息

function get_promise(url){
//返回一个promise对象
	return new Promise(function(resolve, reject){
		let xhr = new XMLHttpRequest();
		xhr.open("GET",url);
		xhr.responseType = "json";
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		xhr.send();
		xhr.onreadystatechange = function(){
			if (this.readyState === 4) {
				if(this.status === 200){
					//请求成功后的回调
					resolve(this.response);
				}else{
					//请求失败的回调
					reject(this);
				}
			}
		}
	});
}

get_promise(url1)
.then((result)=>{
	console.log("全部成功",result);
})
.catch((error)=>{
    console.log("请求失败",error);
})

7.使用ES6的Generator函数实现ajax

案例场景:查询显示每个顾客的所有地址信息(顾客基础信息在一张数据库表中,地址信息在另一张表中)
分析:要想查询显示每个顾客的所有地址信息,需要先将所有顾客信息一 一查询出来,再遍历获取顾客id再去查询这个顾客的地址信息。
要实现这一个功能就不能使用异步操作了,要使用同步操作,但是使用同步操作会使请求时间过长,用户等待浏览器加载网页的时间过长,导致用户体验效果极差。
解决办法:利用Generator函数实现异步函数的同步化

let $ = {
	// 基于promise的异步操作的封装
	get(url){
		// 将异步操作封装到一个承诺对象中
		return new Promise((resolve,reject)=>{
			let xhr = new XMLHttpRequest();
			xhr.open("GET",url);
			xhr.responseType = "json";
			xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
			xhr.send();
			xhr.onreadystatechange = function(){
				if(this.readyState === 4){
					if(this.status === 200){
						// 承诺成功
						resolve(this.response)
					} else {
						// 承诺失败
						reject(this)
					}
				}
			}
		})
	}
}
// 先查询出所有的顾客信息,找到第一个顾客信息的id然后根据该id再查询该顾客的地址信息
function* bar(){
	let customers = yield call($.get,"url")
	console.log("所有顾客:",customers);
	//有多个顾客,现在只取一个
	let id = customers.data[0].id;
	let address = yield call($.get,"url?id="+id)
	console.log("地址信息:",id,address)
}
/*
call是异步函数的执行器{
	1)在上一个请求结束后再去调用下一个请求;
	2)将当前请求结果左右yield表达式的返回值返回
}
*/
function call(handler,params){
	handler(params)
	.then((response)=>{
		// 参数作为上一个yield表达式的返回值
		iterator.next(response)
	})
}
let iterator = bar();
iterator.next();

8.使用ES6的Async 函数实现ajax

Async 函数是Generator函数的语法糖,也就是对Generator函数简化和功能增强。
还是第7点的案例场景,下面使用Async 函数实现

// 基于promise的异步操作的封装
let $ = {
	get(url){
		return new Promise(function(resolve, reject){
			let xhr = new XMLHttpRequest();
			xhr.open("GET",url);
			xhr.responseType = "json";
			xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			xhr.send();
			xhr.onreadystatechange = function(){
				if (this.readyState === 4) {
					if(this.status === 200){
						resolve(this.response);
					}else{
						reject(this);
					}
				}
			}
		});
	}
}

async function foo(){
//await有等待的意思,可以理解为等待请求结束,并且会返回一个promise对象
	let customer = await $.get("url");
	console.log("customer",customer);
	let id = customer.data[0].id;
	let address = await $.get("url?id="+id);
	console.log("address",address);
}
foo();

使用async函数修改过的代码量比使用generator函数实现的代码要少了很多。

9.使用axios实现ajax

axios是一个基于promise的ajax的框架库。
axios即可以运行在浏览器上又可以运行在nodejs上
(当你的项目使用的是vue框架的时候可以使用axios这个库完成异步请求)

<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
//示例代码
//响应拦截,请求响应回来达到浏览器前的操作
axios.interceptors.response.use(function(response){
	console.log("=======interceptors===");
	return response;//一定要返回,不然后面的then方法就获取不到数据进行处理
},function(error){
	//当任何一个ajax请求出现异常的话都会打印错误信息!
	console.log("拦截器异常")
	return Promise.reject(error);
})
axios({
	url:"",//请求地址
	method:"post",//请求类型
	data:{//请求数据
		realname:"张三test",
		telephone:"1827723309"
	},
	headers:{//请求头
		"Content-Type":"application/x-www-form-urlencoded"
	},
	//请求发送前对请求数据的操作
	transformRequest:[(data,headers)=>{
		// 请求发送前将data转换为查询字符串
		let q = "";
		for(let key in data){
			let val = data[key];
			q+=key+"="+val+"&"
		}
		//截取掉最后一个多余的&符号
		return q.slice(0,q.length-1);
	}]
})
.then((response)=>{
	console.log(response);
})
.catch((error)=>{
	console.log("异常信息",error);
})

axios使用方法(部分)
axios(config)
返回值:返回一个ajax承诺对象
参数:
config 是配置对象
{
url,地址
method,请求方法
data, 请求体参数(post请求)
params , 请求行参数(get请求)
headers:{请求头
“Content-Type”:“application/json”
},
responseType:“json”,响应数据累得
withCredentials:false, 默认不携带cookie
baseURL, // 基础路径
timeout, // 5000 请求超时的最大时间
transformRequest:[(data,headers)=>{},()=>{}]
在请求发送到服务器端之前允许我们对data进行处理,一般用于编码
transformResponse:[(data)=>{}]
在响应结果达到then/catch之前对结果进行处理,data为后端返回来的原始数据
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: ‘brackets’})
},
序列化params为查询字符串。get方式传递的参数需要拼接在浏览器地址栏的url的后面,只能为查询字符串

此文章为作者本人原创,仅限于作者本人的学习总结记录,若有错误之处请留言提出。

你可能感兴趣的:(学习笔记)