详解ajax、fetch、axios的区别

众所周知它们都用来发送请求,其实它们区别还蛮大的。这也是面试中的高频题,本文将详细进行讲解。

1. ajax

英译过来是Aysnchronous JavaScript And XML,直译是异步JSXMLXML类似HTML,但是设计宗旨就为了传输数据,现已被JSON代替),解释一下就是说XML作为数据传输格式发送JS异步请求。但实际上ajax是一个一类技术的统称的术语,包括XMLHttpRequestJSCSSDOM等,它主要实现网页拿到请求数据后不用刷新整个页面也能呈现最新的数据

下面我们简单封装一个ajax请求【面试高频题】:

const ajaxGet = function (url) {const xhr = new XMLHttpRequest()xhr.open('get', url)xhr.onreadystatechange = () => {if (xhr.readyState == 4) {if (xhr.status >= 200 && xhr.status < 400) {console.log(xhr.response);  // 响应结果}}}xhr.onerror = (error) => {console.log(error, xhr.status)}xhr.send()
}

2. fetch

它其实就是一个JS自带的发送请求的一个api,拿来跟ajax对比是完全不合理的,它们完全不是一个概念的东西,适合拿来和fetch对比的其实是xhr,也就是上面封装ajax请求的代码里的XMLHttpRequest,这两都是JS自带的发请求的方法,而fetchES6出现的,自然功能比xhr更强,主要原因就是它是基于Promise的,它返回一个Promise,因此可以使用.then(res => )的方式链式处理请求结果,这不仅提高了代码的可读性,还避免了回调地狱(xhr通过xhr.onreadystatechange= () => {}这样回调的方式监控请求状态,要是想在请求后再发送请求就要在回调函数内再发送请求,这样容易出现回调地狱)的问题。而且JS自带,语法也非常简洁,几行代码就能发起一个请求,用起来很方便,据说大佬都爱用。

它的特点是:

  • 使用 promise,不使用回调函数。
  • 采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
  • 通过数据流对象处理数据,可以提高网站性能。

下面我们简单写个fetch请求的示例:

// get请求
fetch('http://127.0.0.1:8000/get').then(res => {if (!res.ok) {throw new Error('请求错误!状态码为:', res.status)}return res.text()
}).then(data => {console.log(data);
})
// post请求
fetch('http://127.0.0.1:8000/post', {method: 'post',headers: {'Content-Type': 'application/json'},mode: 'no-cors',  // 设置cors表示只能发送跨域的请求,no-cors表示跨不跨域都能发body: JSON.stringify({name: 'zhangsan',age: 18})
}).then(res => {return res.json()
}).then(data => {console.log(data);
})

3. axios

axios是用于网络请求的第三方库,它是一个库。axios利用xhr进行了二次封装的请求库,xhr只是axios中的其中一个请求适配器,axios在nodejs端还有个http的请求适配器;axios = xhr + http;它返回一个Promise。【项目中经常需要封装的axios】

它的特点:

  • 在浏览器环境中创建 XMLHttpRequests;在node.js环境创建 http 请求
  • 返回Promise
  • 拦截请求和响应
  • 自动转换 JSON 数据
  • 转换请求数据和响应数据
  • 取消请求

它的基础语法是:

// 发送 Get 请求
axios({method: 'get',url: '',params: {}  // 查询query使用params
})
// 发送 Post 请求
axios({method: 'post',url: '',data: {}  // 请求体body用data
})

下面我们在vue项目中封装一个使用axios实现的请求。

libs/config.js:配置文件

const serverConfig = {baseUrl: "http://127.0.0.1:8000", // 请求基础地址,可根据环境自定义useTokenAuthentication: false, // 是否开启token认证
};
export default serverConfig;

libs/request.js:封装请求

import axios from "axios";  // 第三方库 需要安装
import serverConfig from "./config";
// 创建axios实例
const apiClient = axios.create({baseURL: serverConfig.baseUrl, // 基础请求地址withCredentials: false, // 跨域请求是否需要携带cookieheaders: {Accept: "application/json","Content-Type": "application/json",},timeout: 10000, // 请求超时时间
});// 请求拦截
apiClient.interceptors.request.use((config) => {// 请求发送前的处理逻辑 比如token认证,设置各种请求头啥的// 如果开启token认证if (serverConfig.useTokenAuthentication) {// 请求头携带tokenconfig.headers.Authorization = localStorage.getItem("token");}return config;},(error) => {// 请求发送失败的处理逻辑return Promise.reject(error);}
);// 响应拦截
apiClient.interceptors.response.use((response) => {// 响应数据处理逻辑,比如判断token是否过期等等// 代码块return response;},(error) => {// 响应数据失败的处理逻辑let message = "";if (error && error.response) {switch (error.response.status) {case 302:message = "接口重定向了!";break;case 400:message = "参数不正确!";break;case 401:message = "您未登录,或者登录已经超时,请先登录!";break;case 403:message = "您没有权限操作!";break;case 404:message = `请求地址出错: ${error.response.config.url}`;break;case 408:message = "请求超时!";break;case 409:message = "系统已存在相同数据!";break;case 500:message = "服务器内部错误!";break;case 501:message = "服务未实现!";break;case 502:message = "网关错误!";break;case 503:message = "服务不可用!";break;case 504:message = "服务暂时无法访问,请稍后再试!";break;case 505:message = "HTTP 版本不受支持!";break;default:message = "异常问题,请联系管理员!";break;}}return Promise.reject(message);}
);export default apiClient;

/api/index.js:配置请求接口,这里一个get一个post

import apiClient from "@/libs/request";let getInfo = (params) => {return apiClient({url: "/get",method: "get",params,  // axios的get请求query用params});
};
let postInfo = (params) => {return apiClient({url: "/post",method: "post",data: params,  // axios的post请求body用data});
};
export default {getInfo,postInfo,
};

App.vue:用于测试请求结果

<script>
import api from './api/index.js'
export default {data() {return {isH5: true}},created() {this.init()},methods: {init() {api.getInfo().then(res => {console.log(res.data);})api.postInfo({name: 'zhangsan',age: '18'}).then(res => {console.log(res.data);})}},
}
</script>

结果如下:
在这里插入图片描述
在这里插入图片描述

4. 总结

总结一部分区别如下:【这三个东西差别真的很大】

Ajaxfetchaxios
类型术语,技术的统称js内置的api第三方库
是否使用xhr二次封装
是否返回Promise

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235332.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android14之解决Pixel手机联网出现感叹号(一百八十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

景联文科技:以高质量数据赋能文生图大模型

1月5日&#xff0c;在智求共赢・中国AIGC产业应用峰会暨无界AI生态合作伙伴大会上&#xff0c;中国AIGC产业联盟联合无界AI发布了《中国AIGC文生图产业白皮书2023》&#xff0c;从AIGC文生图发展历程、主流工具、产业实践以及规模预测等多个维度&#xff0c;全面揭示了中国AIGC…

Vue中的class和style绑定

聚沙成塔每天进步一点点 本文内容 ⭐ 专栏简介动态绑定class对象语法数组语法 动态绑定style对象语法多重值 ⭐ 写在最后 ⭐ 专栏简介 Vue学习之旅的奇妙世界 欢迎大家来到 Vue 技能树参考资料专栏&#xff01;创建这个专栏的初衷是为了帮助大家更好地应对 Vue.js 技能树的学习…

TS 36.331 V12.0.0-过程(2)-连接控制(3)-RRC连接释放

​本文的内容主要涉及TS 36.331&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

Spring MVC 的RequestMapping注解

RequestMapping注解 使用说明 作用&#xff1a;用于建立请求URL和处理请求方法之间的对应关系。 出现位置&#xff1a; 类上&#xff1a; 请求 URL的第一级访问目录。此处不写的话&#xff0c;就相当于应用的根目录。写的话需要以/开头。它出现的目的是为了使我们的 URL 可以…

Web实战丨基于django+html+css+js的学院门户网站

文章目录 写在前面项目概述基本信息项目需求 项目框架程序设计运行结果项目总结 写在后面 写在前面 本期内容&#xff1a;基于DjangoHtmlCssJavaScript的学院门户网站 项目需求&#xff1a; pythondjango 项目下载地址&#xff1a;https://download.csdn.net/download/m0_6…

JAVA课程设计--类京东购物车设计

目录 小组成员 负责模块&#xff1a; 程序介绍&#xff1a; 1.前期调查&#xff1a; 1.1京东购物车页面 首页 购物车界面 商品信息界面 搜索界面 1.2程序设计页面 首页 购物车页面 商品信息界面 搜索界面&#xff1a; 2.使用环境&#xff1a; 3.技术支持 前端V…

Provide/Inject 依赖注入(未完待续)

父组件传递给子组件数据&#xff0c;通过props&#xff0c;但是需要逐层传递 provide/Inject 的推出就是为了解决这个问题&#xff0c;它提供了一种组件之间共享此类值的方式,不必通过组件树每层级显示地传递props 目的是为了共享那些被 认为对于一个组件树而言是全局的数据 p…

海外代理IP在游戏中有什么作用?

随着科技的飞速发展&#xff0c;手机和电脑等电子产品已成为互联网连接万物的重要工具&#xff0c;深度融入我们的日常生活&#xff0c;我们借助互联网完成工作、休闲和购物等任务&#xff0c;以求提升生活质量。 不仅如此&#xff0c;网络游戏也是人们心中最爱&#xff0c;它…

【51单片机】独立按键控制LED灯

不同于上篇文章只用代码控制&#xff0c;这次我们要再加上独立按键一同控制LED灯 目录 独立按键控制LED亮灭&#xff1a;代码实现&#xff1a; 独立按键控制LED状态&#xff1a;代码实现&#xff1a; 独立按键实现二进制LED显示&#xff1a;代码实现&#xff1a; 独立按键控制…

cpp_10_多重继承_钻石继承_虚继承

1 多重继承 一个类可以同时从多个基类继承实现代码。 1.1 多重继承的内存布局 子类对象内部包含多个基类子对象。 按照继承表的顺序依次被构造&#xff0c;析构的顺序与构造严格相反。 各个基类子对象按照从低地址到高地址排列。 // miorder.cpp 多重继承&#xff1a;一个子…

跑代码相关 初始环境配置

是看了这个视频&#xff1a;深度学习python环境配置_哔哩哔哩_bilibili 总结的个人笔记 这个是从零开始配python环境的比较好的经验教程&#xff1a; 深度学习python的配置&#xff08;Windows&#xff09; - m1racle - 博客园 (cnblogs.com) 然后关于CUDA和cuDNN&#xff…

武汉灰京文化:跨平台游戏的崛起,破壁无界,畅游全场!

随着科技的飞速发展&#xff0c;游戏平台之间的界限逐渐模糊&#xff0c;许多优秀的游戏已经不再只局限于单一的游戏设备平台。无论你身处何处&#xff0c;只要有网络连接&#xff0c;你就可以随时随地畅玩自己喜欢的游戏&#xff0c;而无需更换设备或重新安装&#xff0c;这无…

UniRepLKNet实战:使用UniRepLKNet实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集一些问题 摘要 大核卷积神经网络&#xff08;ConvNets&#xff09;近年来受到广泛关注&#xff0c;但仍存在两个关键问题需要进一步研究。首先&#xff0c;目前的大型卷积神经网络架构大…

docker 安装redis (亲测有效)

目录 1 安装 1 安装 1 将redis 的 tar 包 上传到服务器 上传之后tar 包&#xff0c;将他变成镜像 输入docker images,发现目前是没有镜像的&#xff0c;现在将tar 包变成镜像 docker load -i redis.tar以上就将tar 包变成镜像了 现在在宿主机找一个地方&#xff0c;存放数据…

Pytorch的GPU版本安装,在安装anaconda的前提下安装pytorch

本文基于conda安装GPU版本的PyTorch 文章目录 一、CUDA1.下载CUDA [点击下载](https://developer.nvidia.com/cuda-toolkit-archive)2.cuDNN [下载](https://developer.nvidia.com/login) 二、pytorch下载1.下载 [pytorch](https://pytorch.org/)2.查看cuda版本3.找到对应的版…

前缀和算法模板

一维前缀和 算法用途&#xff1a;快速求出数组中某一连续区间的和 一维前缀和算法模板 1、预处理出一个 dp 数组 要求原数组存储在 n 1 的空间大小中&#xff0c;其中后 n 个空间存数据。 dp数组&#xff0c;数组开 n 1个空间&#xff0c;dp[i] 表示 [ 1, i ] 区间内所有…

PyQt5零基础入门(二)——QLabel控件

前言 QLabel控件可以视为是一个标签项&#xff0c;具有显示文本、图像的作用。在本篇文章中将介绍QLabel控件的常见用法。 例子 显示文本 import sys from PyQt5.QtWidgets import *if __name__ "__main__":app QApplication([])label QLabel(Hello world!)la…

系统存储架构升级分享

一、业务背景 系统业务功能&#xff1a;系统内部进行数据处理及整合, 对外部系统提供结果数据的初始化(写)及查询数据结果服务。 系统网络架构: • 部署架构对切量上线的影响 - 内部管理系统上线对其他系统的读业务无影响 •分布式缓存可进行单独扩容, 与存储及查询功能升级…

String#intern

1.intern方法 intern()方法可以在运行期间向字符串中动态加入字符串实例的方式&#xff0c;它的功能很简单,总结起来就一句话 可以在运行时向字符串池中添加字符串常量 添加的原则是&#xff0c;如果常量池中存在当前字符串&#xff0c;则直接返回常量池中它的引用&#xff1b…