JavaScript下载文件导出到本地的两种实现方式
作者:辰风沐阳
本文介绍了JavaScript中文件下载的两种实现方式,浏览器对文件处理取决于类型和服务器的响应头设置,zip/docx等文件会触发下载,而图片/视频等会在浏览器中打开,文章提供了两种下载方案,需要的朋友可以参考下
前言
JavaScript 点击跳转文件地址时,有的文件会直接下载,而有的文件则在浏览器中直接打开,这主要取决于浏览器对文件类型的处理方式和服务器的响应头设置
浏览器对文件类型的处理
- 需要下载的文件:zip、docx 等文件,通常会触发下载
- 可在浏览器中打开的文件:图片(png、jpg)、视频(mp4)、文本文件(txt)等,浏览器会尝试打开这些文件
跨域和安全策略
- 如果文件来自不同域名,浏览器的安全策略(CORS)可能会影响文件的处理方式
- 某些文件可能因为安全原因被浏览器阻止直接打开,从而触发下载
a 标签的 download 属性
通过动态创建一个 a 标签,并设置 href 和 dowload 属性来触发下载
适用于同源或支持 cors 的跨域文件下载,也可以下载一个 base64 格式的文件
function download(url, fileName) {
const a = document.createElement("a")
a.href = url
a.download = fileName
a.click()
}
使用示例:后端接口返回一个 base64 格式的二维码图片,前端按钮需要实现点击按钮将图片下载到本地的功能
download('data:image/png;base64,iVBORwxxxxx', 'qrcode.png')
将网络地址文件下载到本地
从指定 URL 下载文件并触发并触发浏览器的下载行为,这种实现方式可以绕过浏览器的同源策略限制
- 检测 url 地址,然后获取文件名称
- 使用 XMLHttpRequest 发起文件下载请求
- onreadystatechange 下载状态监控,监听请求状态变化
- onload 处理下载完成后的逻辑,请求成功时创建一个 a 标签触发浏览器的下载行为
// 下载文件并导出本地
function downloadFile(url, name = '') {
// 检测文件地址
if (url.substr(0, 4) !== 'http') {
throw new Error("请传入一个网络地址");
}
// 获取文件名称
let fileName;
if (name) {
const index = url.lastIndexOf('.')
fileName = name + (index === -1 ? url : url.substr(index))
} else {
const index = url.lastIndexOf('/')
fileName = index === -1 ? url : url.substr(index + 1)
}
// 执行文件下载
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
const url = window.URL.createObjectURL(xhr.response)
const a = document.createElement('a');
a.href = url
a.download = fileName
a.click()
} else {
console.log('文件下载失败');
}
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status == 200) {
console.log('文件下载成功');
}
} else if (xhr.readyState === 3) {
console.log('文件下载中');
}
}
xhr.send();
}
使用示例:
// 下载文件(导出时默认使用原文件名)
downloadFile('https://img.xxx.com/thumb/xxxx.png')
// 下载文件,并且指定文件名称(不需要写文件后缀名,会自动拼接)
downloadFile('https://img.xxx.com/thumb/xxxx.png', 'qrcode')
到此这篇关于JavaScript下载文件导出到本地的两种实现方式的文章就介绍到这了,更多相关JavaScript下载文件导出到本地内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
