如何安全的进行数据获取!!

获取数据的方式

fetch可能是我们在 JavaScript 获取数据最常见的方式。

但是,我们用fetch获取数据的的代码很有可能存在安全问题:

代码示例:

const res = await fetch('/user')
const user = await res.json()

上面这段代码虽然简单好用,但存在许很多问题。

  • 问题一、缺少“错误处理”

当然你可能会说这个问题很好解决嘛,给她添加一个try/catch就好了,遇到错误就会抛出了嘛!

代码示例:

try {const res = await fetch('/user')const user = await res.json()
} catch (err) {// 处理错误的代码
}

当然,这样可以确实可以对我们的错误进行处理了。遇到错误的时候也会抛出,但是就算这样写了还是存在很多的问题,对错误的覆盖能力不全面。

  • 问题二:无法识别部分错误代码

在这里,我们假设user实际上是一个用户对象。我们假设我们得到了响应200

但是fetch不会针对非 200 的状态抛出错误,因此如果你收到了400(错误请求)、401(未授权)、404(未找到)、500(内部服务器错误)或各种其他问题都不会进行错误抛出。

那你可能有会说了那我们用个if进行判断然后对不同的错误码进行分类处理不就好了!

于是我们就有了下面的代码

try {const res = await fetch('/user')if (!res.ok) {switch (res.status) {case 400: /* 错误处理 */ breakcase 401: /* 错误处理 */ breakcase 404: /* 错误处理 */ breakcase 500: /*错误处理 */ break}}// User 已经是我们最新的数据了const user = await res.json()
} catch (err) {// 错误处理
}

现在,我们算是基本实现了fetch对数据的安全获取了. 但是这样写是很臃肿且笨重的,因为每次都必须重写写一次错误的处理逻辑,而如果是团队开发的话对每个成员的要求会更高,要求每个同事都要按照同样的逻辑来处理请求。而且在可读性方面,也是很差的,维护起来很麻烦。

那么我们可不可以换一种更优雅的方式来处理我们的逻辑代码呢?

更优雅的方式

我们可以使用throw来处理我们的不同的错误响,而不是使用switch/case.

try {const res = await fetch('/user')if (!res.ok) {throw new Error('错误的响应')}const user = await res.json()
} catch (err) {// 错误处理
}

但是我们还剩下最后一个问题——就是当我们需要处理错误时,我们丢失了很多有用的上下文。我们无法在 catch 块中访问,因此查看处理错误时我们上并不知道响应的状态代码或错误的详细信息。

这会让我们debug变的很困难,很难去查错。那我们要怎么才能拿到error的上下文呢?

最好的方法可能是创建我们自己的自定义错误类,并且在错误类中转发响应的详细信息:

代码:

class ResponseError extends Error {constructor(message, res) {super(message)this.response = res}
}try {const res = await fetch('/user')if (!res.ok) {throw new ResponseError('错误的响应信息(error的上下文信息)', res)}const user = await res.json()
} catch (err) {//我们可以拿到错误的详细信息,也就是error的上下文switch (err.response.status) {case 400: /* 错误处理 */ breakcase 401: /* 错误处理 */ breakcase 404: /* 错误处理 */ breakcase 500: /* 错误处理 */ break}
}

现在我们保留状态代码等error信息,这样可以让我们的用户了解错误的原因的也能让我们更好的处理错误。

例如,我们可以提醒用户500我们遇到了问题,并可以让客户联系我们的进行解决。

或者如果状态为401,则他们当前未授权,可能需要重新登录等。

封装类

虽然上面的代码可以解决我们的所有问题,但是它仍然存在一个不稳定性,就是代码的健壮性取决于开发人员的个人素质和能力。我们的的请求安全并不能等到统一的保障。

我们可以对我们代码进行封装,然后使用时进行导出引用就行了

class ResponseError extends Error {constructor(message, res) {this.response = res}
}export async function myFetch(...options) {const res = await fetch(...options)if (!res.ok) {throw new ResponseError('错误响应的信息', res)}return res
}

然后我们可以按下面的方式去使用它:

try {const res = await myFetch('/user')const user = await res.json()
} catch (err) {// 错误的处理代码
}

在我们的封装代码中,最好确保有一个统一的方式来处理错误。因为这里面包括给用户的警报、日志记录等。

开源的解决方案

当然如果我们的水平还没有达到可以自己封装一个完善的请求类时我们也可以去网上使用一些别封装好的请求类,

axios

  • axios是一个非常流行的 JS 请求数据的库,它已经帮我们解决了上面我们探讨的几个问题。
try {const { data } = await axios.get('/user')
} catch (err) {// 错误处理代码
}

我觉得 Axios 的唯一缺点是包太大,如果我们只是在一个项目获取一个很简单的数据时使用axios需要引入一个11kb的包,,反而会使我们的项目变的臃肿。

Redaxios

如果你觉得项目的大小对你更重要是你可以选择Redaxios

  • Redaxios使用有 Axios 一样的 API,但不到大小却不到[1kb]
import axios from 'redaxios'
// use as you would normally

Wretch

还有一个不错的选项是Wretch,它是 Fetch封装成的一个非常小的包,和 Redaxios 一样。Wretch 的特别之处在于它在很大程度上还原了原生的数据请求方法,但是它帮我们封装了很多的错误处理代码。

const user = await wretch("/user").get()// Handle error cases in a more human-readable way.notFound(error => { /* ... */ }).unauthorized(error => { /* ... */ }).error(418, error => { /* ... */ }).res(response => /* ... */).catch(error => { /* uncaught errors */ })

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

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

相关文章

阿里拍卖资产推荐算法 召回进展年中总结

阿里拍卖是阿里巴巴旗下拍卖平台,覆盖房产、机动车、土地、债权等类目。召回策略作为推荐场景的第一环,决定了整个推荐系统的上限,目前包含了包括向量召回、I2I、LBS2I、C2I等多路召回。召回的核心目标是尽可能的返回用户所有可能会感兴趣的商…

DataOps真能“降本增效”?

在各行各业中,越来越多的公司开始重视收集数据,并寻找创新方法来获得真实可行的商业成果,并且愿意投入大量时间和金钱来实现这一目标。 据IDC称,数据和分析软件及云服务市场规模在 2021 年达到了 900 亿美元,随着企业继…

CSDN自定义模块全攻略,DIY系统原有样式打造专属个性化主页!

个人主页:学习前端的小z 个人专栏:HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! 文章目录 💯如何通过HTMLCSS自定义模板diy出自己的个性化csdn主页&#x…

明日开考!2024年全国青少年人工智能创新挑战赛及真题

Scratch实验室2024-06-21讯 2024年全国青少年人工智能创新挑战赛【编程创作与信息学专项赛】第二轮将在明天(2024年6月22日)举行,请参加的同学积极备考,参加选拔赛的青少年需通过“人工智能创新挑战赛”专题页面点击“参加选拔赛”…

RocketMQ快速入门:集成spring, springboot实现各类消息消费(七)附带源码

0. 引言 rocketmq支持两种消费模式&#xff1a;pull和push&#xff0c;在实际开发中这两种模式分别是如何实现的呢&#xff0c;在spring框架和springboot框架中集成有什么差异&#xff1f;今天我们一起来探究这两个问题。 1. java client实现消息消费 1、添加依赖 <depen…

uniapp获取视频第一帧作为封面图

uniapp获取视频第一帧作为封面图&#xff0c;前提是在oss里面存储的 视频路径 ‘?x-oss-processvideo/snapshot,t_0,f_jpg’ <image :src"item.video_url ?x-oss-processvideo/snapshot,t_0,f_jpg" mode"aspectFill"></image>

学生如何利用假期提升个人能力?

学生利用假期提升个人能力可以通过多种方式实现&#xff0c;以下是一些建议&#xff1a; 1. **学习新技能**&#xff1a;利用假期时间学习一门新语言、编程、艺术、音乐、体育等&#xff0c;这些技能不仅能够丰富个人生活&#xff0c;还能在未来的学业和职业发展中发挥作用。 …

JavaScript流程控制分支

目录 一、流程控制 二、顺序流程控制 三、分支流程控制 if 语句 1.分支结构 2.if 语句 3.if else 语句 &#xff08;双分支语句&#xff09; 4.if else if 语句 &#xff08;多分支语句&#xff09; 四、三元表达式 五、分支流程控制switch语句 1.分支流程控制switch语句 …

什么是iPaaS?

一、iPaaS简介 iPaaS&#xff0c;即集成平台即服务&#xff08;Integration Platform as a Service&#xff09;&#xff0c;是一种基于云计算的自助服务模型&#xff0c;它为企业提供了一种标准化的应用程序集成方式。能够促进开发、执行和治理集成流程&#xff0c;连接本地和…

正定矩阵(Positive Definite Matrix)

正定矩阵&#xff08;Positive Definite Matrix&#xff09; flyfish Positive&#xff08;正数&#xff09; &#xff1a;在数学和统计学中&#xff0c;通常指大于零的数。在矩阵理论中&#xff0c;一个矩阵被称为正定&#xff0c;是因为它的性质类似于正数的性质。 Defini…

真的不用太焦虑,普通人怎么选都是错

作为一个在职场摸爬滚打多年的过来人&#xff0c;我想跟大家分享一些我的感悟。 这些年看着身边的年轻人们&#xff0c;总是为工作的选择而焦虑不已&#xff1a;他们担心选错了行业&#xff0c;误入歧途&#xff1b;担心选错了公司&#xff0c;前途渺茫。然而&#xff0c;我想告…

STM32 运行atof函数进入hard fault中断

目前为了糊口,做了硬件工程师,因此博客也很久没更新了。目前也只能业余时间自己玩玩喜欢的东西。 最近在研究FOC时候,发现STM32在运行“atof”函数时候,导致程序进入了hard fault中断中。 事情的起因是这样的: 我已经通过Jlink的RTT功能,替代了单片机的串口日志输出。翻阅…

裁员裁到大动脉,是一种什么体验!

大家好啊&#xff0c;我是董董灿。 降本增效是每个当老板的人都喜欢挂在嘴边的口头禅&#xff0c;尤其是行业不景气&#xff0c;公司发展遇到瓶颈的时候。 大部分公司降本增效的手段其实非常相似&#xff0c;比较容易实施的手段也就那几种。 要么搞设备自动化和流程自动化&a…

Anthropic 发布新AI模型Claude 3.5 Sonnet

&#x1f989; AI新闻 &#x1f680; Anthropic 发布新AI模型Claude 3.5 Sonnet 摘要&#xff1a;Anthropic 发布了其最强 AI 模型 Claude 3.5 Sonnet。速度更快、处理细微差别和幽默的能力提升&#xff0c;且支持编写、编辑和执行代码。该模型通过公司网站、iPhone 应用及 A…

【Qt6.3 基础教程 11】 深入探索列表型控件:QListWidget和QComboBox

文章目录 前言QListWidget&#xff1a;便捷的项目列表主要特性示例&#xff1a;使用QListWidget QComboBox&#xff1a;下拉选择的高效实现主要特性示例&#xff1a;使用QComboBox 结合Model/View架构使用总结 前言 在任何现代用户界面中&#xff0c;列表是展示项目集合的重要…

笔记-python map函数

map()函数是Python内置的高阶函数&#xff0c;它接收一个函数f和一个list作为参数。通过将函数f依次应用于list的每个元素&#xff0c;map()函数会生成一个新的list并返回。 例如&#xff0c;对于list [1, 2, 3, 4, 5, 6, 7, 8, 9]&#xff0c;如果我们想要计算list中每个元素…

数据库系统概念(第八周 第一堂)(规范化关系数据库设计)(强推学习!!!)

目录 前言 E-R模型质量低的深层原因 数据依赖 函数依赖 主属性/非主属性 逻辑蕴含与闭包 Armstrongs Axiom 求解F闭包算法 求解属性集闭包算法 属性集闭包的作用 候选码求解理论和算法 候选码求解理论 无关属性 检验方法 正则覆盖 关系模式的设计 关系…

【深度学习】GPT-2,Language Models are Unsupervised Multitask Learners,【语言建模】

论文&#xff1a;https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf 文章目录 摘要引言方法2.1 训练数据集2.2 输入表示2.3 模型3. 实验3.1 语言建模3.2 Children’s Book Test3.3 LAMBADA3.4 Winograd Sc…

自动驾驶学习-车载摄像头ISP(2)

背景 智能驾驶ISP&#xff08;Image Signal Processor&#xff0c;图像信号处理器&#xff09;在自动驾驶和辅助驾驶系统中扮演着至关重要的角色。 典型的ISP通常会对摄像头输出的RAW数据先做黑电平矫正&#xff08;BLC&#xff09;、坏点矫正&#xff08;DPC&#xff09;、数…

如何DIY出专属个性化的CSDN主页?一招教你搞定!

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 &#x1f4af;如何通过HTMLCSS自定义模板diy出自己的个性化csdn主页&#x…