不多BB,直接上代码:
export type FileRequestType = {
url: string
way?: ResponseType
option?: Object
onfail?: (err: any) => void
onsuccess?: (data: any) => void
}
// 下载文件
export const FileRequestDownLoad = async ({
url = '',
onsuccess,
onfail,
option = {
headers: {
Authorization: `Bearer ${getToken()}`,
'Content-Type': 'application/pdf',
responseType: 'arraybuffer',
},
},
}: FileRequestType) => {
const res = await fetch(url, option)
const result = await res.arrayBuffer()
if (res.ok && !!onsuccess) {
onsuccess(result)
} else if (!res.ok && !!onfail) {
onfail(result)
} else {
return result
}
}
传递的option类型自定义,signal同时可以取消当前请求 类似xhr.abort()
option = {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
body: JSON.stringify(''), //传递的对象
signal: controller.signal,
responseType: way,
},
下载文件放法2,添加下载进度的信息
由于第一次请求回的fetch的res只能读取一次
(1. 要么使用流读取器,要么使用 reponse 方法来获取结果。)
// 下载进度
type DownloadPercent = {
url: string
option?: Object
onprocess: (now: number, all: number) => void
onsuccess: (data: any) => void
}
export const RequestPercent = async ({
url = '',
option = {
headers: {
Authorization: `Bearer ${getToken()}`,
'Content-Type': 'application/pdf',
responseType: 'arraybuffer',
},
},
onsuccess,
onprocess,
}: DownloadPercent) => {
const response = (await fetch(url, option)) as any
const reader = response?.body.getReader()
// 文件总长度
const contentLength = +response.headers.get('content-length')
let receivedLength = 0
const chunks = []
// eslint-disable-next-line no-constant-condition
while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
chunks.push(value)
receivedLength += value.length
onprocess(receivedLength, contentLength)
}
// 这里的chunksAll 已经是ArrayBuffer的数据类型了,可以直接返回,也可以转为blob处理
const chunksAll = new Uint8Array(receivedLength)
let position = 0
for (const chunk of chunks) {
chunksAll.set(chunk, position)
position += chunk.length
}
onsuccess(chunksAll)
return chunksAll
}
总结:
ArrayBuffer和Blob一样,都是二进制数据的容器,而ArrayBuffer相比更为底层。ArrayBuffer的数据,是可以按照字节去操作的,而Blob的只能作为一个整的对象去处理。
常规数据类型转换:
1. `TextEncoder` => `ArrayBuffer`
//uint8Array
const res = new TextEncoder().encode('data')
const arr = res.buffer
2. `blob` => `ArrayBuffer`
//借助blob
const blob = new Blib([data], { type: 'application/pdf' })
const utf8decoder = new TextDecoder()
blob.arrayBuffer().then(buffer=>{
console.log(buffer)
const text = utf8decoder.decode(buffer)
// text =>arraybuffer
console.log(text)
})