一文详解JavaScript如何安全的进行数据获取

 更新时间:2023年03月19日 14:01:28   作者:zayyo  
这篇文章主要为大家介绍了JavaScript如何安全的进行数据获取方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

获取数据的方式

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: /* 错误处理 */ break
      case 401: /* 错误处理 */ break
      case 404: /* 错误处理 */ break
      case 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: /* 错误处理 */ break
    case 401: /* 错误处理 */ break
    case 404: /* 错误处理 */ break
    case 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 */ })

以上就是一文详解在JavaScript中如何安全的进行数据获取的详细内容,更多关于JavaScript数据安全获取的资料请关注脚本之家其它相关文章!

相关文章

  • 微信小程序页面滑动屏幕加载数据效果

    微信小程序页面滑动屏幕加载数据效果

    这篇文章主要为大家详细介绍了微信小程序页面滑动屏幕加载数据效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Javascript实现简单二级下拉菜单实例

    Javascript实现简单二级下拉菜单实例

    这篇文章主要介绍Javascript实现二级下拉菜单的具体过程,需要的朋友可以参考下
    2014-06-06
  • Webpack的Loader和Plugin的区别

    Webpack的Loader和Plugin的区别

    这篇文章主要介绍了Webpack的Loader和Plugin的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • JavaScript随机打乱数组顺序之随机洗牌算法

    JavaScript随机打乱数组顺序之随机洗牌算法

    这篇文章主要介绍了JavaScript随机打乱数组顺序之随机洗牌算法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • electron 引入node服务的操作方法

    electron 引入node服务的操作方法

    这篇文章主要介绍了electron 引入node服务的操作方法,引入node服务很简单,直接在electron的主体中引入就可以了,对electron 引入node服务感兴趣的朋友一起看看吧
    2024-03-03
  • 详解TypeScript中模块化开发指南

    详解TypeScript中模块化开发指南

    在编程中,模块是指将相关的代码封装在一起,形成一个独立的单元,在这篇文章中,我们将深入探讨在TypeScript中如何定义、导入和导出模块,感兴趣的可以了解一下
    2023-06-06
  • ES6 Promise.race的用法详解

    ES6 Promise.race的用法详解

    本文主要介绍了ES6 Promise.race的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • 利用微信小程序制作属于自己的Icon图标

    利用微信小程序制作属于自己的Icon图标

    项目中常常需要使用到字体图标,微信小程序中使用字体图标与在平常的web前端中类似但是又有区别,下面这篇文章主要给大家介绍了关于利用微信小程序制作属于自己的Icon图标的相关资料,需要的朋友可以参考下
    2022-04-04
  • JS类中定义原型方法的两种实现的区别

    JS类中定义原型方法的两种实现的区别

    JS类中定义原型方法的两种实现的区别...
    2007-03-03
  • 在JavaScript中生成不可修改属性对象的方法

    在JavaScript中生成不可修改属性对象的方法

    这篇文章主要介绍了在 JavaScript 中生成不可修改属性对象的方法,包括相关函数及原理,并列举了在状态管理、数据缓存、函数式编程等场景中的实际应用,还通过代码示例进行了详细说明,需要的朋友可以参考下
    2024-12-12

最新评论