前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue(JavaScript)下载文件方式汇总

Vue(JavaScript)下载文件方式汇总

作者头像
十玖八柒
发布2022-08-01 09:27:06
2.2K0
发布2022-08-01 09:27:06
举报
文章被收录于专栏:ahzoo.cn的博客分享

Window下载

实现原理:直接用浏览器访问下载链接,唤起浏览器下载功能

代码语言:javascript
复制
window.location.href = '下载链接';
// 或者
window.open('下载链接');

缺点:无法(从前端)自定义下载文件名,下载可预览文件(图片,音乐、视频等)时,会跳转新的界面

A标签下载

实现原理:创建一个a标签,然后点击它,即把下面的标签用js创建出来

代码语言:javascript
复制
<a href="下载链接" download="文件名(如:a.zip)">下载</a>

a标签download+url

代码语言:javascript
复制
const a = document.createElement('a')
a.href = '下载链接'
a.download = '文件名'
a.style.display = 'none'
a.target = 'downloadFile'
document.body.appendChild(a) // 兼容火狐 
a.click()
document.body.removeChild(a) // 移除a标签

缺点:下载可预览文件时,会跳转新的界面,对于跨域请求download属性会失效,也就是说无法自定义下载文件名

window.URL+blob

下载文件

由于上面是方法会打开新的界面,所以我们需要对下载链接进行一些处理,比如转为blob格式:

代码语言:javascript
复制
// 这里需要发送一次请求将下载地址里的文件转为blob格式,进行下载(发送请求时同样会存在跨域问题,如果跨域的话需要在nginx配置代理)
const blob = await fetch('下载链接').then(res => res.blob())
content = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = content
a.download = '文件名'
document.body.appendChild(a) // 兼容火狐 
a.click()
document.body.removeChild(a) // 移除a标签
window.URL.revokeObjectURL(content)  // 释放content对象

也可以用ajax请求转为blob格式:

代码语言:javascript
复制
const x = new window.XMLHttpRequest()
x.open('GET', '下载链接', true)
x.responseType = 'blob'
x.onload = () => {
    const content = window.URL.createObjectURL(x.response)
    const a = document.createElement('a')
    a.href = content
    a.download = '文件名'
    document.body.appendChild(a) // 兼容火狐 
    a.click()
    document.body.removeChild(a) // 移除a标签
    window.URL.revokeObjectURL(content)  // 释放content对象
}
x.send()

自然也可以发送axios请求:

代码语言:javascript
复制
axios({
  method: 'get',
  url: '下载链接'
  responseType: 'blob',
}).then((res) => {
  if (res && res.status === 200) {
    const content = window.URL.createObjectURL(new Blob([response.data]));
    const a = document.createElement('a') // 创建a标签
    a.href = content
    a.download = '文件名'
    document.body.appendChild(a) // 兼容火狐 
    a.click()
    document.body.removeChild(a) // 移除a标签
    window.URL.revokeObjectURL(content)  // 释放content对象
  }
}

缺点:需要对下载链接进行请求,将下载的文件转为blob格式,所以自然少不了跨域问题,并且blob格式无法在手机端浏览器下载,所以建议和上面的配合使用,手机端用上面的url方法下载,电脑端用blob

下载文字

如果是文字的话,则无需再发送请求,可直接将文字转为blob格式

代码语言:javascript
复制
const blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
// 只有上面的转为blob格式不同,下面的都是一样的
content = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = content
a.download = '文件名'
document.body.appendChild(a) // 兼容火狐 
a.click()
document.body.removeChild(a) // 移除a标签
window.URL.revokeObjectURL(content)  // 释放content对象

From表单下载

代码语言:javascript
复制
const url = '下载地址'
const form = document.createElement('form')
form.style.display = 'none'
form.setAttribute('target', '_blank')
form.setAttribute('method', 'get')
form.setAttribute('action', url)
// 创建一个input控件:<input type="hidden" name="请求参数名" value="请求参数值"/>
const input = document.createElement('input')
// 设置input属性
input.setAttribute('type', 'hidden')
input.setAttribute('name', '请求参数名');
input.setAttribute('value', '请求参数值');

form.appendChild(input)
document.body.appendChild(form)
form.submit()
document.body.removeChild(form)

下载可预览文件时,会跳转新的界面

Iframe下载

iframe下载不会出现向a标签那样的跳转问题,但是iframe兼容性较差,反正我在测试中没成功过

代码语言:javascript
复制
const url = '下载地址';
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.display = 'none';
iframe.onload = function() {
    document.body.removeAttribute(iframe);
}
document.body.appendChild(iframe);

Canvas下载图片

代码语言:javascript
复制
const url = '图片下载地址'
const a = document.createElement('a')
a.setAttribute('download', '文件名称')
const image = new Image()
// 添加时间戳,防止浏览器缓存图片
image.src = url + '?timestamp=' + new Date().getTime()
// 设置 crossOrigin 属性,解决图片跨域报错(还需要在后端设置允许跨域请求,否则仍会出现跨域问题)
image.setAttribute('crossOrigin', 'Anonymous')
image.onload = () => {
  // 将图片转为base64
  const canvas = document.createElement('canvas')
  canvas.width = image.width
  canvas.height = image.height
  const ctx = canvas.getContext('2d')
  ctx.drawImage(image, 0, 0, image.width, image.height)
  // 获取图片后缀名
  const extension = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase()
  // 部分图片地址可能没有后缀名,默认为png格式
  const base64Url = canvas.toDataURL('image/' + extension, 1)
  // 也可以直接写死后缀名
  // const base64Url = canvas.toDataURL("image/png")

  a.href = base64Url
  a.click()
}

缺点:同样需要处理跨域问题

FileSaver下载文件

使用FileSaver下载文件时仍然存在跨域问题

下载:

代码语言:javascript
复制
npm install file-saver --save

# 或者:
bower install file-saver

引入:

代码语言:javascript
复制
import fileSaver from 'file-saver'

下载文字

代码语言:javascript
复制
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
fileSaver.saveAs(blob, "hello world.txt");

下载图片(画布)

代码语言:javascript
复制
var canvas = document.getElementById("canvasid");
canvas.toBlob(function(blob) {
    fileSaver.saveAs(blob, "image.png");
});

下载网络资源

代码语言:javascript
复制
fileSaver.saveAs('地址', '名称')

下载文件(file)

代码语言:javascript
复制
var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});
fileSaver.saveAs(file);

下载文件(blob)

代码语言:javascript
复制
fileSaver.saveAs(blob, '文件名')

示例

转为blob格式的方法,上面已经写了很多个了,这里取其中一个做示范:

代码语言:javascript
复制
const blob = await fetch('下载链接').then(res => res.blob())
fileSaver.saveAs(blob, '文件名')
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Window下载
  • A标签下载
    • a标签download+url
      • window.URL+blob
        • 下载文件
        • 下载文字
      • From表单下载
      • Iframe下载
      • Canvas下载图片
      • FileSaver下载文件
        • 下载文字
          • 下载图片(画布)
            • 下载网络资源
              • 下载文件(file)
                • 下载文件(blob)
                  • 示例
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档