1.介绍
1.1XHR介绍
XMLHttpRequest(XHR)是一种浏览器提供的API,用于在客户端和服务器之间发送HTTP或HTTPS请求,支持异步数据传输。它是AJAX(Asynchronous JavaScript and XML)技术的核心,允许网页在不重新加载的情况下更新部分内容。
XHR的主要特点包括:
- 支持异步和同步请求(默认异步)。
- 可以发送各种HTTP方法(GET、POST、PUT、DELETE等)。
- 能够处理多种数据格式(JSON、XML、文本等)。
- 提供事件监听机制(如
onload、onerror、onprogress)
基本用法示例
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // 异步请求
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error('请求失败');
}
};
xhr.onerror = function() {
console.error('请求出错');
};
xhr.send();
1.2Promise 介绍
Promise是JavaScript中用于处理异步操作的对象,代表一个可能现在、将来或永远不可用的值。它解决了回调地狱(Callback Hell)问题,使异步代码更易读和维护。
Promise的三种状态:
- Pending(进行中):初始状态,未完成或拒绝。
- Fulfilled(已成功):操作成功完成。
- Rejected(已失败):操作失败或被拒绝。
基本用法示例
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('数据加载成功');
} else {
reject('数据加载失败');
}
}, 1000);
});
fetchData
.then((result) => {
console.log(result); // 输出:数据加载成功
})
.catch((error) => {
console.error(error); // 输出:数据加载失败
});
1.3Axios介绍
Axios 是一个基于 Promise 的 HTTP 客户端,专为浏览器和 Node.js 设计。它支持拦截请求和响应、转换请求和响应数据、自动转换 JSON 数据,并提供客户端防御 XSRF 的功能。
支持 Promise API
axios 的所有请求均返回 Promise 对象,支持链式调用和 async/await 语法,简化异步操作。
拦截请求和响应
可以通过拦截器在请求发送前或响应返回后统一处理数据,例如添加全局 headers 或错误日志。
自动转换数据
请求数据(如 POST)和响应数据(如 JSON)会自动转换格式,无需手动处理。支持 ArrayBuffer、FormData 等数据类型。
取消请求
使用 CancelToken 或 AbortController 取消正在进行的请求,适用于组件卸载时中止冗余请求。
基本用法示例
接下来将使用XHR和Promise将对无参请求、参数请求、Json格式的Post请求等进行简易实现。
//无参请求
axios({
method: 'get',
url: 'http://ajax-api.itheima.net/api/province',
}).then((response)=>{
console.log(response)
})
//查询参数请求
axios({
method: 'get',
url: 'http://ajax-api.itheima.net/api/city',
params:{
pname:'辽宁省'
}
}).then((response)=>{
console.log(response)
})
//post请求
axios({
method: 'post',
url: 'http://ajax-api.itheima.net/register',
data:{
username:'张三',
password:'123456'
}
}).then((response)=>{
console.log(response)
})

2.实现
2.1无参请求
axio的无参请求传入了对象作为配置。配置其method、url、params和data等,因此myAxios传入config来作形参配置。
//无参请求
axios({
method: 'get',
url: 'http://ajax-api.itheima.net/api/province',
}).then((response)=>{
console.log(response)
})
代码中promise的resolve和then是对应的,reject和catch是对应的。目前代码中执行执行无参请求。
function myAxios(config){ //config配置形参
return new Promise((resolve,reject)=>{ //返回promise对象用于管理异步任务及其结果
let xhr=new XMLHttpRequest(); //创建xhr对象
xhr.open('GET',config.url); //配置method和url
xhr.addEventListener('loadend',()=>{ //对xhr对象添加监听事件
if(xhr.status>=200 & xhr.status<300){
resolve(xhr.response) //如果请求成功,则执行为promise设置的then方法将data作为参数传入。
}else{
reject(new Error('请求失败')) //如果请求失败,则执行catch方法,同样传参。
}
})
xhr.send(); //发送请求
})
}
let ax=myAxios({
url:'http://ajax-api.itheima.net/api/province'
}).then((result)=>{
console.log(result) //成功执行这个函数
}).catch((error)=>{
console.log(error) //失败执行这个函数
})
console.log(ax)

2.2参数请求
axios中传入了params对象作为查询参数。
//查询参数请求
axios({
method: 'get',
url: 'http://ajax-api.itheima.net/api/city',
params:{
pname:'辽宁省'
}
}).then((response)=>{
console.log(response)
})
查询参数是URL中用于向服务器传递额外信息的键值对,通常出现在问号? 之后,格式为 key=value,多个参数用 &连接。例如:
//http://ajax-api.itheima.net/api/city?city=XX&province=xx
有两种方法,使用URLSearchParams来接收params对象.toString()将对象转为需要的查询参数字符串。当然可以采用方法二自己来实现。
params={
pname:'河北省'
}
//方法一
let urlParams=new URLSearchParams(params)
let urlStr='?'+urlParams.toString()
console.log(urlStr)//pname=%E6%B2%B3%E5%8C%97%E7%9C%81 这是url编码
//方法二
let arr=[];
for(let key in config.params){
arr.push(`${key}=${config.params[key]}`)
}
config.url+='?'+arr.join('&')
进行修改后
function myAxios(config){
return new Promise((resolve,reject)=>{
let xhr=new XMLHttpRequest();
//修改部分
let urlStr=''
if(config.params){
let urlParams=URLSearchParams(config.params)
urlStr='?'+urlParams.toString()
}
xhr.open('GET',config.url+urlStr);
xhr.addEventListener('loadend',()=>{
if(xhr.status>=200 & xhr.status<300){
resolve(xhr.response)
}else{
reject(new Error('请求失败'))
}
})
xhr.send();
})
}
2.3请求体请求
HTTP 请求方法
HTTP 协议定义了多种请求方法,用于执行不同的操作。以下是常见的 HTTP 请求方法及其用途:
GET
用于请求指定资源的数据。GET 请求通常用于检索信息,不应修改服务器上的数据。GET 请求的参数会附加在 URL 中。
POST
用于向服务器提交数据,通常用于表单提交或上传文件。POST 请求的数据包含在请求体中,而不是 URL 中。
PUT
用于更新服务器上的资源。PUT 请求会替换目标资源的全部内容。如果资源不存在,PUT 可能会创建它。
DELETE
用于删除服务器上的指定资源。
通过修改open函数参数,||运算符会返回第一个为真的内容,如果method为空则为假,会采用GET请求。这样就可以根据传入的method来更改请求方法。
xhr.open(config.method||'GET',config.url);
如果有传入的data则,先设置请求头的内容类型,再将data转为json格式发送出去。
function myAxios(config){
return new Promise((resolve,reject)=>{
let xhr=new XMLHttpRequest();
let urlStr=''
if(config.params){
let urlParams=URLSearchParams(config.params)
urlStr='?'+urlParams.toString()
}
xhr.open(config.method||'GET',config.url+urlStr);
xhr.addEventListener('loadend',()=>{
if(xhr.status>=200 & xhr.status<300){
resolve(xhr.response)
}else{
reject(new Error('请求失败'))
}
})
//修改部分
if(config.data){ //如果有data则,设置请求体的内容类型为json
xhr.setRequestHeader('Content-Type','application/json')
xhr.send(JSON.stringify(config.data))//所以要将对象转为json进行发送
}else{
xhr.send();
}
})
}
data={
username:'张三',
password:'123456'
}
myAxios({
method:'POST',
url:'http://ajax-api.itheima.net/register',
data
}).then((result)=>{
console.log(result)
}).catch((error)=>{
console.log(error)
})
以下是走到了catch中的结果。

更改username为李四的成功结果。
![]()
以上便是对Axios部分功能的简单实现,之后还可以继续进行内容的丰富。
用XHR和Promise模拟Axios
16万+

被折叠的 条评论
为什么被折叠?



