记录问题
接收api返回值的时候,后端返回的可能是文件流或者是blob对象,但是也可能是json对象或者字符串。
碰到过这个问题的朋友可能知道,在接收二进制信息的时候,一般会设置arrayBuffer或者是blob。不然,axios默认接收字符串,当你保存的文件在打开时就会报格式错误。
因为如果在接收二进制数据时没有显式地设置 responseType 为 "blob",则响应的数据会被视为字符串类型,并且会自动被转换为 UTF-8 字符串。在这种情况下,如果你将响应的数据直接保存为文件,就会出现文件格式错误的情况,因为实际的文件内容已经被转换为了字符串,与文件格式不符
分歧来了
如果,我们包装了axios,做了统一的错误处理,这时,一个接口定义的返回信息没有明确的类型,他可能是blob也可能是json。这是我们应该怎么办,为单独的一个接口去独立使用axios或者单独封装一个新的方法,去解决这个问题。
我查了一些资料,设想了一下axios的包装是做的了一个处理,应对上边的问题。
首先,统一使用 responseType 为 ArrayBuffer 类型来接收 API 返回的数据,一般情况下都可以接收.
这样就解决了需要根据API返回值来区分responseType。
然后再通过对数据的判断,来确定是什么类型的数据,并做出处理。
上代码, cv党可以粘贴过去改改了。
import axios from 'axios' // 创建 Axios 实例,并设置默认配置
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
})
// 添加请求拦截器
instance.interceptors.request.use(
(config) => {
// 在请求发送之前,可以对请求进行统一处理
// 例如添加请求头、对请求参数进行加密等
// 设置默认responseType
config.responseType = 'arraybuffer'
return config
},
(error) => {
// 请求错误时的处理
return Promise.reject(error)
}
)
// 添加响应拦截器
instance.interceptors.response.use(
(response) => {
// 在响应返回之前,可以对响应进行统一处理
// 例如解密响应数据、对响应数据进行格式化等
let data
/* 此处接收默认值为ArrayBuffer的对象 */
if (response.data instanceof ArrayBuffer) {
// do something with the ArrayBuffer object
const contentType = response.headers['content-type']
/* 判断返回头是不是json格式,如果是,做json转义 */
if (contentType.includes('application/json')) {
data = JSON.parse(Buffer.from(response.data).toString('utf8'))
}
if (contentType.includes('application/pdf')) {
data = new Blob([response.data], { type: 'application/pdf' })
}
/* .......根据自定义需求去做转义, */
}
return data
},
(error) => {
// 响应错误时的处理
return Promise.reject(error)
}
)
做个记录,用来了解一些原理
axios 和 XMLHttpRequest 核心上是一样的
Axios 和 XMLHttpRequest 在核心上都是用来向服务器发送请求并接收响应的客户端技术,因此它们的核心功能是类似的。
两者最大的不同之一是 Axios 提供了更加便捷的 API 和更加友好的语法糖,可以更加方便地发起请求和处理响应。Axios 还提供了丰富的配置选项、请求拦截器和响应拦截器等功能,可以更加灵活地控制请求和响应的行为。
另外,Axios 在处理异常和错误时也提供了一些便捷的方法,如通过 catch 捕获错误,或通过 interceptors 处理请求和响应的错误等。
总之,Axios 在功能上可以看作是对 XMLHttpRequest 进行了进一步封装和增强,提供了更加友好的 API 和更加便捷的使用方式。但它们的核心功能仍然是相同的:向服务器发送请求并接收响应。
responseType作用是什么
responseType 是 XMLHttpRequest(XHR)对象的一个属性,它指定了在接收到服务器响应后,如何将响应数据解析和处理。
XHR对象是用于在Web应用程序中与服务器进行异步通信的一种技术。通常情况下,XHR 对象接收到服务器响应后会自动将响应数据解析成字符串格式。但是,如果需要处理二进制数据、JSON 数据等其他类型的响应数据,则需要使用 responseType 属性来指定。
responseType 属性可以设置为以下几种类型:
- "" 或 "text":默认值,表示将响应数据作为字符串处理。
- "arraybuffer":表示将响应数据作为 ArrayBuffer 对象处理。
- "blob":表示将响应数据作为 Blob 对象处理。
- "document":表示将响应数据作为 XML 文档对象处理。
- "json":表示将响应数据作为 JSON 对象处理。
通过设置 responseType 属性,开发人员可以直接获取到需要的数据类型,从而避免手动解析响应数据。这样可以提高代码效率,简化代码逻辑,并且使应用程序更加可维护和易于开发。
arraybuffer 是什么意思
ArrayBuffer 是一种在 JavaScript 中表示二进制数据的对象类型。它允许开发人员直接处理二进制数据,而不需要通过字符串或其他数据类型来间接表示。
ArrayBuffer 对象表示一段连续的内存区域,可以用来存储不同类型的数据,如整数、浮点数、布尔值、字节等等。开发人员可以使用 TypedArray 或 DataView 对象来读写 ArrayBuffer 中的数据。
ArrayBuffer 在浏览器中广泛应用于处理图像、音频、视频、WebSockets 等功能。它还可以用于在 Web Worker 中进行高效的数据处理。
统一使用arraybuffer的话,可以接收所有格式么
统一使用 ArrayBuffer 类型来接收 API 返回的数据,一般情况下都可以接收。因为 ArrayBuffer 是一种通用的二进制数据类型,可以表示任何类型的二进制数据。同时,很多 JavaScript 库和框架都支持使用 ArrayBuffer 类型来处理二进制数据。
不过,需要注意的是,使用 ArrayBuffer 接收数据后,需要根据实际的数据类型进行解析和处理。因为 ArrayBuffer 只是一种二进制数据的容器,不包含具体的数据类型信息。在解析数据时,需要根据具体的数据格式来解析数据,例如将数据转换为字符串、数字、图片等等。
另外,如果 API 返回的是文件流,使用 ArrayBuffer 可能会存在一些兼容性问题。因为不同浏览器对文件流的实现方式可能不同,需要针对不同的浏览器进行适配。如果要处理文件流,建议使用 Fetch API 或 XMLHttpRequest 对象,并根据具体浏览器实现方式进行处理。
怎么查看返回格式
需要在 Response 的 headers 中查看 API 返回的数据类型,可以查看 "content-type" 属性。 "content-type" 属性表示服务器返回的数据的 MIME 类型,通常用于指定数据的格式和编码方式。在使用 Fetch API 或 XMLHttpRequest 获取数据时,服务器通常会在响应头中添加 "content-type" 属性。
如果返回的是文件流(如 ReadableStream 对象),通常 "content-type" 属性的值会是一个流式数据格式(如 application/octet-stream)或者具体的数据格式(如 application/pdf、image/png 等)。
如果返回的是 Blob 对象,"content-type" 属性的值通常对应具体的数据格式(如 application/pdf、image/png 等),但是也有可能是流式数据格式(如 application/octet-stream)。在这种情况下,需要根据实际情况进行处理。
学习中,欢迎交流指正