浅谈AJAX

104 阅读12分钟

一、什么是AJAX

定义:AJAX 是异步 JavaScriptXML

简单来说:使用 XMLHttpRequest 对象与服务器通信。

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

二、怎么使用AJAX

  1. 使用 axios 库,与服务器进行 数据通信
    • 基于 XMLHttpRequest 封装,代码简单。
    • Vue、React 项目都在使用 axios
  2. 学习 XMLHttpRequest 对象的使用,了解 AJAX 底层原理。
2.1、 axios 的使用
  1. 引入 axios.js
  2. 使用 axios 函数
    • 传入 配置对象
    • 然后使用 .then()回调函数接收结果,并做后续处理。
axios({
    url:''
}).then(res => {

})

总结:

  1. AJAX 有什么用?
    • 浏览器与服务器之间的的通信,动态数据交互。
  2. AJAX 如何学习?
    • 先掌握 axios 再了解 XMLHttpRequest 原理。
  3. axios使用步骤?
    • 先引入 axios
    • 然后使用 axios 语法。
2.2、什么是 URL

定义:统一资源定位符

缩写:URL 或称统一资源定位器,定位地址,URL地址,俗称网页地址,简称网址,是因特网上标准的资源地址,如同网络上的门牌。

概念:URL 就是统一资源定位器,简称网址,用于访问网络上的资源。

2.3、URL 的组成

URL 的组成:协议,域名、资源路径。

协议:http 协议,超文本传输协议,规定浏览器和服务器之间传输数据的格式。

协议分为两种:http和https

域名:标记服务器在互联网中的方位

资源路径:标记资源在服务器中的具体位置

总结:

1.URL的组成?

2.URL 有哪几部分,分别有什么作用?

2.4、URL查询参数

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

语法:xxx.xx?参数名1=值&参数名2=值

2.5、axios 查询参数

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

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

axios({
    url:'',
    params:{
    }
}).then(res=>{

})

总结:

  1. URL 查询参数有什么用?
  2. axios要如何携带查询参数?
2.6、常用的请求方法
常用的请求方法操作
get获取参数
post提交数据
put修改数据(全部)
delete删除数据
patch修改数据(部分)
2.7、axios请求配置

URL:请求的URL网址

method:请求方法(不区分大小写)

data:提交数据

总结:

  1. 请求方法表明对服务器资源的操作,最常用的两个是?
  2. axios核心配置
2.8、axios 错误处理

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

axios({
    url:''
    params:{}
}).then(res=>{

}).catch(err=>{

})
2.9、HTTP 协议,请求报文

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

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

2.9.1、请求报文格式
  1. 请求行:请求方法,URL,协议
  2. 请求头:以键值对的格式携带的附加信息,比如:Content-Type
  3. 空行:分隔请求头,空行之后的是发送给服务器的资源
  4. 请求体:发送的资源

总结:

  1. 浏览器发送给服务器的内容叫做请求报文
  2. 请求报文的组成
  3. 通过浏览器的网络面板查看请求报文
3.0、HTTP 协议,响应报文
  1. HTTP 协议:规定了浏览器发送及服务器返回内容的格式
  2. 响应报文:服务器按照 HTTP 协议要求的格式,返回给浏览器的内容
3.0.1、请求报文格式
  1. 响应行(状态行) :协议、HTTP 响应状态码。状态信息
  2. 响应头:以键值对的格式携带的附加信息,比如:Content-Type
  3. 空行:分隔响应头,空行之后的是服务器返回的资源
  4. 响应体:返回的资源
3.1、响应状态码

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

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

总结:

  1. 响应报文的组成
  2. HTTP响应状态码用来表明请求是否成功完成
3.2、接口文档

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

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

3.3、收集表单输入的值 -- 插件(form-serialize

作用:快速收集表单元素的值

使用:两个参数

参数1:要获取哪个表单的数据

参数2:配置对象

hash:设置获取的数据结构(true:js对象,false:查询字符串)

empty:设置是否获取空值(true:获取空值,false:不获取空值)

const form = document.querySelector('.xxxxx');
cosnt data = serialize(form,{hash:true,empty:true})

三、AJAX原理 -- XMLHttpRequest

定义:XLMLHttpRequest(XHR) 对象用于与服务器交互。通过XMLHttpRequest 可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequestAJAX编程中被大量使用。

关系:axios内部采用XMLHttpRequest服务器交互。

好处:掌握使用XHR服务器进行数据交互,了解axios内部原理。

3.1、使用XMLHttpRequest
  • 步骤:
    • 创建XMLHttpRequest对象。
    • 配置请求方法url地址。
    • 监听loadend事件,接收响应结果,addEventListenter
    • 发送请求
const xhr = new XMLHttpRequest();
xhr.open('get','');
xhr.addEventListenter('loadend',()=>{
    console.log(xhr.response)
})
xhr.send()
3.2、设置请求头
  • 步骤:
    • 请求头设Content-Type:application/json
    • 请求体携带JSON字符串。
const xhr = new XMLHttpRequest();
xhr.open('get','');
xhr.addEventListenter('loadend',()=>{
    console.log(xhr.response)
})
// 告诉服务器,我传递的内容类型,是JSON字符串
xhr.setRequestHeader('Content-Typ','application/json')
// 准备数据并转成JSON字符串
const user = {'username':'username','password':'password'}
const userStr = user.toString();
xhr.send(userStr)

总结:

  1. AJAX原理是什么?
  2. 为什么学习XHR
    • 有更多与服务器数据通信方式。
    • 了解 axios 内部原理。
  3. XHR使用步骤
3.3、Promise

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

好处:

  1. 逻辑更清晰
  2. 了解axios函数内部运作机制
  3. 能解决回调函数地狱问题

语法:

// 创建Promise对象
const p = new Promise((resolve,reject)=>{
  // 执行异步任务 - 并传递结果
  // 成功调用:resolve(值)触发then()执行
  // 失败调用:reject(值)触发catch()执行
  // 接收结果
}).then(res=>{
  // 成功
}).catch(err=>{
  // 失败
})

总结:

  1. 什么是Promise
    • 表示(管理)一个异步操作最终状态和结果值的对象
  2. 为什么学习Promise
    • 成功和失败状态,可以关联对应处理程序
    • 了解axios内部原理
  3. Promise使用步骤
3.4、Promise三种状态

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

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

待定(pending):初始状态,既没有兑现,也没有拒绝

已兑现(fulfilled):操作成功完成(.then()回调函数)

已拒绝(rejrcted):操作失败(.catch()回调函数)

  • 注意:
    • Promise对象一旦被兑现/拒绝就是已敲定了,状态无法再被改变
    • Promise对象创建时,内部代码立马执行

总结:

  1. Promise那三种状态?
  2. Promise状态有什么用?
    • 状态改变后,调用关联函数
3.5、封装简易版axios
  • 步骤:
    • 定义myAxios函数,接收配置对象,返回Promise对象
    • 发起XHR请求,默认请求方法GET
    • 调用成功/失败的处理程序
    • 使用myAxios函数,获取省份列表展示
function myAxios(config){
    return new Promise(((resolve,reject))=>{
        const xhr = new XMLHttpRequest();
        xhr.open(config.method || 'get',config.url)
        xhr.addEventListenter('loadend',()=>{
           if(xhr.status >= 200 && xhr.status < 300){
             resolve(JSON.parse(xhr.response))
           }else{
             reject(new Error())
           }
    })
        })
        xhr.open()
    })
}

myAxios({
    url:"",
    method:"POST",
}).then({
}).catch({
})
3.5.1、封装简易版axios -- 查询参数
  • 步骤
    • 判断是否有params选项,携带查询参数
    • 使用URLSearchParams转换,并携带到url
    • 使用myAxios函数,获取省份查询 列表展示
function myAxios(config){
    rethrn new Promise(((resolve,reject))=>{
        const xhr = new XMLHttpRequest();
        if(config.params){
            cosnt paramsObj = new URLSearchParams(config.params);
            const paramsStr = paramsObj.toString();
            config.url += `?{paramsStr}`
        }
        xhr.open(config.method || 'get',config.url)
        xhr.addEventListenter('loadend',()=>{
            if(xhr.status >= 200 && xhr.status <= 300){
                resolve(JSON.parse(xhr.response))
            }else{
                reject(new Error())
            }
        })
        xhr.send();
    })
}

myAxios({
    url:"",
    method:"POST",
    params:{
        username:"username",
        password:"password"
    }
}).then({
}).catch({
})
3.5.2、封装简易版axios -- 请求体数据
  • 步骤
    • 判断是否有data选项,携带请求体
    • 转换数据类型,在send中发送
    • 使用myAxios函数,完成注册用户
function myAxios(){
    rethrn new Promise(((resolve,reject))=>{
        const xhr = new XMLHttpRequest()
        if(config.params){
            cosnt paramsObj = new URLSearchParams(config.params);
            const paramsStr = paramsObj.toString();
            config.url += `?{paramsStr}`
        }
        xhr.open(config.method || 'get',config.url)
        xhr.addEventListenter('loadend',()=>{
            if(xhr.status >= 200 && xhr.status <= 300){
                resolve(JSON.parse(xhr.response))
            }else{
                reject(new Error())
            }
        })
        if(config.data){
            cosnt jsonStr = JSON.stringify(config.data);
            xhr.setRequestHeader('Content-Type','application/json');
            xhr.send(jsonStr);
        }
    })
}
3.6、同步代码和异步代码
  • 同步代码: 我们应该注意的是,实际上浏览器是按照我们书写代码的顺序一行一行地执行程序的。浏览器会等待代码的解析和工作,在上一行完成后才会执行下一行。这样做是很有必要的,因为每一行新的代码都是建立在前面代码的基础之上的。这也使得它成为一个同步程序。
  • 异步代码: 异步编程技术使你的程序可以在执行一个可能长期运行的任务的同时继续对其他事件做出反应而不必等待任务完成。与此同时,你的程序也将在任务完成后显示结果。

总结:

  1. 什么是同步代码?
    • 逐行执行,需要原地等待结果后,才继续向下执行。
  2. 什么是异步代码?
    • 调用后耗时,不阻塞代码继续执行(不必原地等待),在将来完成后触发一个回调函数。
  3. JSsetTimeout/setInterval,事件,AJAX中哪些是异步代码?
    • `setTimeout/set概念:在回调函数中嵌套回调函数,一直嵌套下去就会形成回调地狱

缺点:可读性差,异常无法捕获,耦合性严重Interval,事件,AJAX` 4. 异步代码如何接收结果? - 依靠回调函数来接收

3.7、回调地狱

概念:在回调函数中嵌套回调函数,一直嵌套下去就会形成回调地狱。

缺点:可读性差,异常无法捕获,耦合性严重。

3.7.1、Promise -- 链式调用

概念:依靠then()方法返回一个新生成的Promise对象特性,继续串联下一环任务,直到结束。

细节:then()回调函数中的返回值。会影响新生成的Promise对象最终状态和结果

好处:通过链式调用,解决回调函数嵌套问题。

image.png Promise链式调用有什么用 总结:

  1. 什么是Promise的链式调用?
    • 使用then函数返回新的Promise对象特性,一直串联下去
  2. then回调函数中,return的值会传给哪里?
    • 传给then函数生成的新的Promise对象
  3. Promise链式调用有什么用?
3.7.2、asyncawait

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

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

  1. async函数和await -- 捕获错误
  • 使用
try ... catch
语句标记要尝试的语句块,并指定一个出现异常时抛出的响应
  • 语法
try{

} catch(error){

}
3.7.3、事件循环(EventLoop

概念:JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。

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

定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制。

总结:

  1. 什么是事件循环?
  2. 为什么有事件循环?
    • JavaScript是单线程的,为了不阻塞JS引擎,设计执行代码的模型
  3. Javascript内部代码是如何执行?
    • 执行同步代码,遇到异步代码交给宿主浏览器环境执行
    • 异步有了结果后,把回调函数放入任务队列排队
    • 当调用栈空闲后,反复调用任务队列里的回电函数
3.7.4、宏任务和微任务

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

  • 异步任务分为:
    • 宏任务:由浏览器环境执行的异步代码
    • 微任务:由JS引擎环境执行的异步代码
任务(代码)执行所在环境
JS脚本执行事件浏览器
setTimeout/setInterval浏览器
AJAX请求完成事件浏览器
用户交互事件浏览器
任务(代码)执行所在环境
Promise对象.then()JS引擎

Promise本身是同步的,而then()catch回调函数是异步的。

注:微任务优先宏任务执行

3.7.5、Promise.all静态方法

概念:合并多个Promise对象,等待所有同时成功完成(或某一个失败,做后续逻辑)

语法:

const p = Promise.all([Promise对象,Promise对象])
p.then({
}).catch({
})
3.7.6、token

概念:访问权限的令牌,本质上是一串字符串

创建:正确登陆后,由后端签发并返回

作用:判断是否有登录状态,控制访问权限

注意: 前端只能判断token有无,而后端才能判断token的有效性。

3.7.7、axios请求拦截器

axios请求拦截器:发起请求之前,触发的配置函数,对请求参数进行额外配置。

axios.interceptors.request.use(function(config){
	const token = token
  if(token && config.headers){
		config.headers.Authorization = `Bearer ${token}`;
    return config;
	},function(err){
		return Promise.reject(error);
  }
);

总结:

  1. 什么是axios请求拦截器?
  2. 什么时候使用axios请求拦截器?
  3. 有公共配置和设置时,统一设置在请求拦截器中?
3.7.8、axios响应拦截器

axios响应拦截器:响应回到then/catch之前,触发的拦截函数,对响应结果统一处理.


axios.interceptors.response.use(function(response){
  	const result = response.data
    return result;
	},function(err){
  // 例子
  if(err?.response?.status === 401){
    
  }
    return Promise.reject(error);
  }
);

总结:

  1. 什么是axios响应拦截器?
  2. 什么时候触发axios响应拦截器?