vue 通过base64实现图片下载功能


Posted in Vue.js onDecember 19, 2020

1. 使用场景

当我们处理图片下载功能的时候,如果本地的图片,那么是可以通过canvas获得图片的base64的,方法如下。但是如果图片的url存在跨域问题的话,下面的方法将行不通,这时候我们可以另辟蹊径,将后台的同学,将图片以base64的形式进行返回。

function getBase64(url){
  //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
  var Img = new Image(),
    dataURL='';
  Img.src=url;
  Img.onload=function(){ //要先确保图片完整获取到,这是个异步事件
    var canvas = document.createElement("canvas"), //创建canvas元素
      width=Img.width, //确保canvas的尺寸和图片一样
      height=Img.height;
    canvas.width=width;
    canvas.height=height;
    canvas.getContext("2d").drawImage(Img,0,0,width,height); //将图片绘制到canvas中
    dataURL=canvas.toDataURL('image/jpeg'); //转换图片为dataURL
  };
}

2. 处理base64,进行下载

处理base64的时候有两点要注意,一个是对ie浏览器的处理,一个是对火狐浏览器的处理

2-1. 我们首先直接处理base64(基于vue)

1.由于后台返回的是纯base64,如果要完成图片的下载功能,必须加上一个前缀

<template>
 <a
  :href="prefixBase64 + qrBase64" rel="external nofollow" rel="external nofollow" 
  download="qrcode.png"
  class="qrcode"
 >
  <img src="static/img/load.png">
 </a>
</template>
 
<script>
 ...
 data () {
  return {
   qrBase64: '', // 二维码对应的base64(在方法里面进行获取)
   prefixBase64: 'data:image/png;base64,', // base64前缀
  }
 }
 ...
</script>

2.采用这种方式可以很好的支持chrome、Firefox、opera、Safari,但是不支持ie,所以我们下面单独处理ie浏览器

2-2. 处理ie浏览器

1.修改代码如下

<template>
 <a
  @click.stop.prevent="handleDownloadQrIMg"
  class="qrcode"
 >
  <img src="static/img/load.png">
 </a>
</template>
<script>
export default {
 methods: {
  // 点击下载图片
  handleDownloadQrIMg() {
   // 这里是获取到的图片base64编码,这里只是个例子哈,要自行编码图片替换这里才能测试看到效果
   const imgUrl = this.prefixBase64 + this.qrBase64;
   // 如果浏览器支持msSaveOrOpenBlob方法(也就是使用IE浏览器的时候),那么调用该方法去下载图片
   if (window.navigator.msSaveOrOpenBlob) {
    let bstr = atob(imgUrl.split(",")[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
     u8arr[n] = bstr.charCodeAt(n);
    }
    let blob = new Blob([u8arr]);
    window.navigator.msSaveOrOpenBlob(blob, "chart-download" + "." + "png");
   } else {
    // 这里就按照chrome等新版浏览器来处理
    let a = document.createElement("a");
    a.href = imgUrl;
    a.setAttribute("download", "chart-download");
    a.click();
   }
  }
 }
};
</script>

2.ok,ie的问题解决了,但是火狐的又不行了

2-3. 兼容方法

1.结合上面两种检测方法,我们只要可以判断浏览器是火狐,然后单独处理就可以实现我们的兼容性了

<template>
 <div>
  <a
   v-if="!isFirefox"
   @click.stop.prevent="handleDownloadQrIMg"
   class="qrcode"
  >
   <img src="static/img/load.png">
  </a>
  <a
   v-if="isFirefox"
   :href="prefixBase64 + qrBase64" rel="external nofollow" rel="external nofollow" 
   download="qrcode.png"
   class="qrcode"
  >
   <img src="static/img/load.png">
  </a>
 
 </div>
 
</template>
 
<script>
export default {
 data() {
  return {
   qrBase64: "", // 二维码对应的base64(在方法里面进行获取)
   prefixBase64: "data:image/png;base64,", // base64前缀
   isFirefox: false
  };
 },
 mounted() {
  // 判断浏览器是否是火狐
  if (navigator.userAgent.indexOf("Firefox") > 0) {
   this.isFirefox = true;
  }
 },
 methods: {
  // 点击下载图片
  handleDownloadQrIMg() {
   // 这里是获取到的图片base64编码,这里只是个例子哈,要自行编码图片替换这里才能测试看到效果
   const imgUrl = this.prefixBase64 + this.qrBase64;
   // 如果浏览器支持msSaveOrOpenBlob方法(也就是使用IE浏览器的时候),那么调用该方法去下载图片
   if (window.navigator.msSaveOrOpenBlob) {
    let bstr = atob(imgUrl.split(",")[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
     u8arr[n] = bstr.charCodeAt(n);
    }
    let blob = new Blob([u8arr]);
    window.navigator.msSaveOrOpenBlob(blob, "chart-download" + "." + "png");
   } else {
    // 这里就按照chrome等新版浏览器来处理
    let a = document.createElement("a");
    a.href = imgUrl;
    a.setAttribute("download", "chart-download");
    a.click();
   }
  }
 }
};
</script>

以上就是vue 通过base64实现图片下载功能的详细内容,更多关于vue 图片下载的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
Vue用mixin合并重复代码的实现
Nov 27 Vue.js
如何实现vue的tree组件
Dec 03 Vue.js
实用的 vue tags 创建缓存导航的过程实现
Dec 03 Vue.js
在vue中使用inheritAttrs实现组件的扩展性介绍
Dec 07 Vue.js
vue实现两个区域滚动条同步滚动
Dec 13 Vue.js
vue项目中openlayers绘制行政区划
Dec 24 Vue.js
vue中使用echarts的示例
Jan 03 Vue.js
vue实现禁止浏览器记住密码功能的示例代码
Feb 03 Vue.js
vue引入Excel表格插件的方法
Apr 28 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
VUE递归树形实现多级列表
Jul 15 Vue.js
Vue中computed和watch有哪些区别
Dec 19 #Vue.js
Vue与React的区别和优势对比
Dec 18 #Vue.js
Vue实现指令式动态追加小球动画组件的步骤
Dec 18 #Vue.js
vue+elementUI动态增加表单项并添加验证的代码详解
Dec 17 #Vue.js
vue 数据操作相关总结
Dec 17 #Vue.js
Vue 组件注册全解析
Dec 17 #Vue.js
vue图片裁剪插件vue-cropper使用方法详解
Dec 16 #Vue.js
You might like
删除数组元素实用的PHP数组函数
2008/08/18 PHP
PHP5.4中json_encode中文转码的变化小结
2013/01/30 PHP
php删除数组元素示例分享
2014/02/17 PHP
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
解决安装WampServer时提示缺少msvcr110.dll文件的问题
2017/07/09 PHP
PHP7 弃用功能
2021/03/09 PHP
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
2009/11/30 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
2012/04/12 Javascript
JavaScript 判断浏览器是否支持SVG的代码
2013/03/21 Javascript
JS 毫秒转时间示例代码
2013/09/22 Javascript
jquery获取复选框被选中的值
2014/04/10 Javascript
jquery判断元素是否隐藏的多种方法
2014/05/06 Javascript
JS实现很酷的EMAIL地址添加功能实例
2015/02/28 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
轻松5句话解决JavaScript的作用域
2016/07/15 Javascript
用jquery的attr方法实现图片切换效果
2017/02/05 Javascript
vue toggle做一个点击切换class(实例讲解)
2018/03/13 Javascript
浅谈python装饰器探究与参数的领取
2017/12/01 Python
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
Python中正则表达式的用法总结
2019/02/22 Python
python实现字典嵌套列表取值
2019/12/16 Python
浅谈django 模型类使用save()方法的好处与注意事项
2020/03/28 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
css3一个简易的 LED 数字时钟实现方法
2020/01/15 HTML / CSS
HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍
2013/01/31 HTML / CSS
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
html如何对span设置宽度
2019/10/30 HTML / CSS
WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要使用自动传回?
2012/02/21 面试题
个人现实表现材料
2014/02/04 职场文书
《永远的白衣战士》教学反思
2014/04/25 职场文书
应届毕业生求职信
2014/05/26 职场文书
安全责任书模板
2014/07/22 职场文书
解除租房协议书
2014/12/03 职场文书
师德培训心得体会2016
2016/01/09 职场文书
uniapp开发小程序的经验总结
2021/04/08 Javascript
Mysql数据库索引面试题(程序员基础技能)
2021/05/31 MySQL