备注: ajax 没有流下载,没有合适的响应类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>
</head>
<body>
<a href="文件下载链接" download="文件名">下载</a>
<button id="download">点击下载</button>
</body>
</html>
const downloadEl = document.getElementById('download')
function downloadBlob(blob, filename) {
const a = document.createElement('a')
const href = window.URL.createObjectURL(blob)
a.href = href
a.download = filename
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
window.URL.revokeObjectURL(href)
}
// 必须支持FileReader
function fileToJson(blob) {
return new Promise((resolve, reject) => {
if (typeof FileReader === undefined) {
return reject({ code: 0, blob })
}
const reader = new FileReader()
reader.onloadend = (res) => {
try {
const jsonRes = JSON.parse(res.target.result)
return resolve(jsonRes)
} catch {
return reject({ code: 0, blob })
}
}
reader.onerror = (err) => {
return reject(err)
}
reader.readAsText(blob)
})
}
function isFile(blob) {
return fileToJson(blob)
.then(jsonRes => {
console.log('error' + jsonRes)
return Promise.reject()
})
.catch(res => {
if (res && res.code === 0) {
console.log('is file')
return blob
}
})
}
function requestFile({ url }, callback) {
axios({
responseType: 'blob',
responseEncoding: 'utf8',
method: 'get',
url
}).then(res => {
callback(res)
})
}
function requestFile({ url }, callback) {
const xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.responseType = 'blob';
xhr.responseEncoding = 'utf8';
xhr.send();
xhr.onload = function() {
// 获取headers
const responseHeaders = xhr.getAllResponseHeaders()
// console.log(responseHeaders, typeof responseHeaders) // 获取不到所有的headers
const arr = responseHeaders.trim().split(/[\r\n]+/);
const headers = {};
arr.forEach(function (line) {
const parts = line.split(': ');
const header = parts.shift();
const value = parts.join(': ');
headers[header] = value;
})
const data = xhr.response
callback({ data, headers })
}
xhr.onprogress = function() {}
xhr.onerror = function() {}
xhr.onabort = function() {}
xhr.onloadend = function() {}
}
function requestFile({ url }, callback) {
const request = new Request(url)
request.headers = {
"Content-type": "application/x-www-form-urlencoded"
}
fetch(request)
.then(response => {
const headers = {}
for (const [key, value] of response.headers) {
headers[key] = value
}
if (response.status === 200) {
return response.blob().then(blob => {
callback({ data: blob, headers })
})
}
})
}
function download({ url, filename }) {
// 获取文件,文件名称,文件大小等等
requestFile({ url }, async ({ data, headers }) => {
console.log(headers)
// 保证后台filename 使用encodeURIComponent 方式编码 否则中文等会乱码
// 保证后台 access-control-expose-headers: 'content-disposition'
const content_disposition = headers['content-disposition']
if (content_disposition) header_filename = decodeURIComponent(content_disposition.split('filename=')[1])
if (!filename) filename = header_filename
// 判断是否是文件
await isFile(data)
// 下载文件
downloadBlob(data, filename)
})
}
function downloadHandle() {
download({
filename: '2022中国显示学术会议会议通知.zip',
url: 'https://s.laoyaoba.com/jwconference/dissertation2022/file/tz.zip'
})
}
downloadEl.addEventListener('click', downloadHandle, false)
nodejs 简单文件下载
https://blog.youkuaiyun.com/Holly1945/article/details/123802482