2024年最新版Ajax+Axios 学习【包含原理、Promise、报文、接口等...】

基础知识

AJAX概念

AJAX概念:是浏览器与服务器进行数据通信的技术。

认识URL

定义:统一资源定位符,简称网址,用于访问网络上的资源。

组成:

  • http协议:超文本传输协议,规定浏览器和服务器之间传输数据的格式。
  • 域名:标记服务器在互联网中方位。
  • 资源位置:标记资源在服务器下的具体位置。

查询参数

定义:浏览器提供给服务器的额外信息,让服务器返回浏览器想要的数据。

语法:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2

常用请求方式

请求方式:对服务器资源,要拽行动的操作

请求方法 操作
GET 获取数据
POST 数据提交
PUT 修改数据(全部)
DELETE 删除数据
PATCH 修改数据(部分)

报文

HTTP协议:规定了浏览器发送及服务器返回内容的格式。

请求报文

请求报文:浏览器按照HTTP协议要求的格式,发送给服务器的内容。

请求报文由以下几个部分组成:

  1. 请求行:包含请求方法、URL和协议。
  2. 请求头 :以键值对格式携带的附加信息,例如 Content-Type
  3. 空行:用于分隔请求头,空行之后是发送给服务器的资源。
  4. 请求体:实际发送给服务器的资源。
调试窗口查看报文

在浏览器任意页面右键找到检查或者直接F12键打开调试窗口。

然后找到网络,找到Fetch/XHR

然后就可以在调试窗口里面查看报文信息啦!

请求头在标头中观看:

响应头就在响应标头中查看:

请求标头保存请求头的信息:

可以点击原始显示原始的请求头信息

请求体在载荷中观看:

响应体就在响应中查看:

如果响应的内容比较多的时候,可以在预览窗口查看,就会以json数据的格式呈现出来。

响应报文

响应报文:服务器按照HTTP协议要求的格式,返回给浏览器的内容。

它由以下几个部分组成:

  1. 响应行(状态行):包含协议、HTTP响应状态码和状态信息。
  2. 响应头 :以键值对格式携带的附加信息,例如 Content-Type
  3. 空行:用于分隔响应头,空行之后是服务器返回的资源。
  4. 响应体:实际返回给浏览器的资源。
HTTP响应状态码

HTTP响应状态码:用来表明请求是否成功完成

状态码 说明
1xx 信息
2xx 成功
3xx 重定向消息
4xx 客户端错误
5xx 服务端错误

接口文档

接口文档:由后端提供的描述接口的文章

接口:使用AJAX和服务器通讯时,使用的URL请求方法,以及参数

Axios

基本使用

使用方法:

  1. 引入axios:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js

    • 可以使用console.log(axios)检验是否拿到了axios对象
  2. 使用axios函数

    使用方法:
    	1. 传入配置对象。
    	2. 再用.then回调函数接收结果,并做后续处理。
    	
    axios({
    	url:'目标资源地址'
    }).then((返回结果)=>{
    	//在then回调函数中,第一个参数就是服务端返回的数据结果
    	//对服务器返回的数据做后续的处理
    })
    

查询参数

语法:使用axios提供的params选项

模版:

axios({
	url:''
	params:{
		参数名:值
	}
}).then(res =>{
	//方法
})

⚠️注意:axios在运行时把参数名和值,会拼接到url?参数名=值

请求配置

语法:使用axios提供的 mothed选项

模版:

  • method:请求的方法(get可以省略不写)

  • data:提交数据

    axios({
    url:'',
    params:{ 参数名:值 },
    method:'请求方法',
    data:{
    参数名:值
    }
    }).then(res =>{
    //方法
    })

错误处理

语法:在then方法的后面,通过点语法调用catch方法,传入回调函数并定义形参

模版:

axios({
	//请求选项
}).then(res =>{
	//处理数据
}).catch(err =>{
	//错误处理
})

AJAX原理

XMLHttpRequest

定义:XMLHttpRequest(XHR)对象用于与服务器交互。axios内部采用XMLHttpRequest与服务器交互。

使用步骤:

  1. 创建一个XHR对象

    const xhr = new XMLHttpRequet()
    
  2. 调用open方法,配置请求方法请求url地址

    xhr.open(请求方式,请求路径)
    
  3. 监听loadend事件,接受响应结果

    xhr.addEventListener('loadend',() = >{
    	//console.log(xhr.response)
    	//转化为json对象
    	console.log(JSON.parse(xhr.response))
    })
    
  4. send方法发起请求

    xhr.send()
    

查询参数

直接在open方法中拼接查询字符串:

xhr.open(get,请求路径?参数名=参数值&参数名2=参数值2&...)

URLSearchParams

将对象格式数据,转化为查询字符串

const obj = new URLSearchParams({
	对象名1,对象名2...
})
const str = obj.toString()

const xhr = new XMLHttpRequet()
xhr.open(请求方式,请求路径?${str})

提交参数

const xhr = new XMLHttpRequet()
xhr.open(post,请求路径)
xhr.addEventListener('loadend',() = >{
	//console.log(xhr.response)
	//转化为json对象
	console.log(JSON.parse(xhr.response))
})
//请求体参数步骤:
// 1. 设置请求头数据类型,根据接口文档设置application/json
xhr.setRequestHeader('Content-Type','applicatio/json')
// 2.在send方法中携带参数
const obj ={
	username:'',
	password:''
}
//3.转化成字符串
const data = JSON.stringfy(obj)

xhr.send(data)

封装简易axios(了解)

步骤:

  1. 定义一个函数,接受配置对象,返回Promise对象

    function myAxios(option){
    	const { url,method } = option
    	return new Promise((resolve,reject) => {
    
    	})
    }
    
  2. 发起XHR请求

    function myAxios(option){
    	const { url,method } = option
    	return new Promise((resolve,reject) => {
    		const xhr = new XMLHttpRequest
    		xhr.open(method,url)
    		xhr.addEventListener('loadend', ()=>{})
    		xhr.send()
    	})
    }
    
  3. 调用成功或失败的处理程序

    function myAxios(option){
    	const { url,method } = option
    	return new Promise((resolve,reject) => {
    		const xhr = new XMLHttpRequest
    		xhr.open(method,url)
    		xhr.addEventListener('loadend', ()=>{
    			resolver(xhr.response)
    		})
    		xhr.send()
    	})
    }
    
  4. 使用封装的函数

    myAxios({
    	url:'',
    	method:''
    }).then(res => {
    	console.log(res)
    })
    

如果需要查询参数:

  1. 调用函数的时候传入params参数

    myAxios({
    	url:'',
    	method:'',
    	params:{
    		参数1:值1...
    	}
    }).then(res => {
    	console.log(res)
    })
    
  2. 基于URLSearchParmas转化并携带url上

    let { url,method,params } = option
    
    params = parmas ? new URLSearchParmas(params).toString():''
    url = params ? url+'?' +params:url
    

如果需要请求参数

  1. 同样的先调用函数传入data 参数

  2. 解构data

    let { url,method,params,data } = option
    
  3. 设置data

    if(data){
    	//1. 设置请求头
    	xhr.setRequestHeader('Content-Type','application/json')
    	//2. 处理数据
    	// data = JSON.stringify(data)
    	//3. 发送请求
    }else{
    	xhr.send(JSON.stringfy(data))
    }
    
  4. 错误处理

    if(xhr.status >= 200 && xhr.status < 300){
    	resolver(JSON.parse(xhr.response))
    }else{
    	reject(new Error(xhr.response))
    }
    

Promise

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果值。

好处:

  1. 逻辑更清晰

  2. 了解axios函数内部运作机制

  3. 能解决回调函数地狱问题

语法:

  1. 创建Promise对象

    const p = new Promise(function(成功,失败){ })
    //一般写成以下👇形式
    
  2. 执行异步操作并传递结果

    const p = new Promise(function (resolve,reject){
    	resolve('成功')
    })
    
    1. 成功调用:resolve(值)触发then
    2. 失败调用:reject(值)触发catch
  3. 接受结果

    p.then(result => {
    	//成功
      })
    p.catch(error => {
    	//失败
    	})
    

Promise三种状态

作用:了解Promise对象如何关联的处理函数,以及代码执行顺序。

概念:一个Promise对象,必然处于以下几种状态之一

状态 含义
待定(pending) 初始状态,既没有被兑现,也没有被拒绝
已兑现(fulfilled) 意味着,操作成功完成
已拒绝(rejected) 意味着,操作失败

状态凝固:Promise的特性,一旦状态从pending修改为其他状态后就不会再次修改了。

Promise+XHR

  1. 创建Promise对象

  2. 在Promise对象中使用XHR

  3. 接受结果,使用Promise对象

    const p = new Promise(function(resolve,reject){
    	const xhr = new XMLHttpRequest()
    	xhr.open(请求方式,请求地址)
    	xhr.addEventListener('loadend',() => {
    		//成功
    		resolve(xhr.response)
    		//失败
    		//reject(xhr.response)
    	})
    	xhr.send()
    })
    
    p.then(result => {
    	//成功
      })
    p.catch(error => {
    	//失败
    	})
    

同步与异步

同步代码:逐行执行,需原地等待结果后才继续向下执行。

异步代码:调用后耗时,不阻塞代码继续执行(不必原地等待),在将来完成后触发一个回调函数。(例子:定时器、Axios、事件)

小习题:

答案:

由此可知,异步代码是通过回调函数来接受结果

回调地狱问题

概念:回调函数嵌套回调函数就是回调地狱

缺点:可读性差,异常无法获取,耦合性严重,牵一发动全身。

链式调用

概念:依靠then()方法会返回一个新生成的Promise对象特性,继续串联下一环任务,直到结束,then回调函数中的返回值会影响新生成的Promise对象最终状态和结果。

then回调函数中,return的值传给了新的Promise对象。

Promise链式调用的作用是解决了回调函数嵌套的问题。

const p = new Promise((resolver,reject) => {
	resolve('成功1')
})

p.then(res => P{
		console.log(res)	//这里打印的是('成功1')
		return new Promise((resolve,reject) =>{
			resolve(res + '成功2')	
		})
	}).then(res => {
		console.log(res)	//这里打印的是(res + '成功2')	
	})
async、await关键字

定义:async函数是使用async关键字声明的函数。async函数是一个构造函数的实例,并且其中允许使用awai关键字。asyncawait关键字让我们可以用一种更加简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise

使用方法:在async函数内,使用await关键字取代then函数,等待获取Promise对象成功状态的结果值。

模版:

async function render(){
	const res = await axios({
		url:'',
		method:''
		})
}
//调用async
render()

注意:

  • await必须用在async修饰的函数内
  • await会组织"异步函数内"代码继续执行,原地等待结果
async函数错误处理

因为async函数只能获取成功状态的结果值,如果发生错误了,这个时候就要使用到try...catch方法来捕获错误。try...catch语句标记要尝试的语句块,并指定一个出现异常时抛出的响应。

语法:

try{
	//要执行的代码
} catch(error){
	//error接受的是错误信息
}

那么我们直接跟上面的代码进行修改:

async function render(){
	try{
		const res = await axios({url:'',method:''})
	} catch(err){
		console.log(new Error(err))	//错误处理
	}
}
//调用async
render()

事件循环

原因:JavaScript单线程(某一刻只能执行一行代码),为了让耗时代码不阻塞其他代码运行,设计了事件循环模型(EventLoop)。

定义:执行和收集异步任务的模型(机制),在调用栈空闲的时候,会反复调用任务列表里面回调函数的执行机制,叫做事件循环。

执行过程:

  1. 执行同步代码,遇到异步代码交给宿主环境执行
  2. 异步有了结果后,把回调函数放入任务队列排队

示例:

这段代码示例,展示了如何使用console.log函数和setTimeout函数来打印数字到控制台。不过,它并不是一个"时间循环",而是展示了JavaScript中的异步执行和事件循环机制。

  1. console.log(1); 立即执行,打印数字1到控制台。
  2. setTimeout(function() { console.log(2); }, 0); 设置了一个定时器,当定时器到期时,会将一个匿名函数加入到事件队列中。这个定时器设置的延迟是0毫秒,意味着它将在当前执行栈清空后的下一个事件循环迭代中执行。打印数字2。
  3. console.log(3); 立即执行,打印数字3到控制台。
  4. setTimeout(function() { console.log(4); }, 2000); 设置了另一个定时器,延迟2000毫秒后执行,打印数字4。
  5. console.log(5); 立即执行,打印数字5到控制台。

执行顺序如下:

  • 首先打印1。
  • 然后设置第一个定时器,但不会立即执行。
  • 接着打印3。
  • 然后打印5。
  • 事件循环继续,第一个定时器到期后执行,打印2。
  • 2000毫秒后,第二个定时器到期执行,打印4。

所以,最终的打印顺序是:1, 3, 5, 2, 4。

宏任务与微任务

ES6之后引入了Promise对象,让JS引擎也可以发起异步任务。

异步任务分为:

  • 宏任务:由浏览器环境执行异步代码
    • js脚本执行事件
    • 定时器
    • AJAX请求完成事件
    • 用户交互事件
  • 微任务:由JS引擎环境执行的异步代码
    • Promise对象.then()方法(⚠️注意:Promise本身是同步的,而then和catch回调函数是异步的)

执行顺序:

  1. 执行第一个script脚本事件宏任务,里面同步代码。
  2. 遇到宏任务/微任务交给数组环境,由结果回调函数进入对应队列
  3. 当执行栈空闲的时候,清空微任务队列,在执行下一个宏任务,循环往复。

示例:

Promise.all方法

作用:合并多个Promise对象,等待所有完成(或某一个失败),做后续逻辑

语法:

const p = Promise.all([Promise对象,Promise对象,...])
p.then(resule =>{	
	//result结果
}).catch(error =>{
	//第一个失败的Promise对象,抛出的异常
})
相关推荐
轻口味23 分钟前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami26 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
虾球xz30 分钟前
游戏引擎学习第55天
学习·游戏引擎
oneouto1 小时前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh321 小时前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
wakangda1 小时前
React Native 集成原生Android功能
javascript·react native·react.js
吃杠碰小鸡1 小时前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html