50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { EventEmitter } from 'events'
|
|
|
|
export const useDownload = (
|
|
url: string,
|
|
filename: string
|
|
): {
|
|
download: () => void
|
|
progressEmitter: EventEmitter
|
|
} => {
|
|
const progressEmitter = new EventEmitter()
|
|
|
|
const download = () => {
|
|
const xhr = new XMLHttpRequest()
|
|
xhr.open('GET', url, true)
|
|
xhr.responseType = 'blob'
|
|
xhr.onprogress = (event) => {
|
|
if (event.lengthComputable) {
|
|
const percentComplete = (event.loaded / event.total) * 100
|
|
progressEmitter.emit('progress', percentComplete)
|
|
}
|
|
}
|
|
xhr.onload = function () {
|
|
if (this.status === 200) {
|
|
const blob = new Blob([this.response], {
|
|
type: 'application/octet-stream',
|
|
})
|
|
const url = window.URL.createObjectURL(blob)
|
|
const link = document.createElement('a')
|
|
link.href = url
|
|
link.setAttribute('download', filename)
|
|
document.body.appendChild(link)
|
|
link.click()
|
|
link.parentNode?.removeChild(link)
|
|
progressEmitter.emit('done')
|
|
} else {
|
|
progressEmitter.emit('error', new Error('资源已过期或不存在'))
|
|
}
|
|
}
|
|
xhr.onerror = function () {
|
|
progressEmitter.emit('error', new Error('网络错误,下载失败'))
|
|
}
|
|
xhr.send()
|
|
}
|
|
|
|
return {
|
|
download,
|
|
progressEmitter,
|
|
}
|
|
}
|