利用canvas实现图片下载功能来实现浏览器兼容问题


Posted in HTML / CSS onMay 31, 2019

前言:项目中需要实现图片下载功能,第一个想到的是使用a标签的download属性来实现,但是在不同浏览器下测试会发现,有的浏览器无效,点击后直接预览图片,所以,上网找到了另外一种兼容不同浏览器的图片下载的方法,那就是利用canvas来处理图片,实现下载;

1.项目中点击事件绑定:

<a href="#" @click.prevent="downloadIamge(imgsrc, name)"><span>{{name}}</span></a>

2.点击事件中操作:

downloadIamge (imgsrc, name) {
      const url = imgsrc
      this.convertUrlToBase64(url).then((base64) => {
        const blob = this.convertBase64UrlToBlob(base64)
        if (getBrowser() === 'IE' || getBrowser() === 'Edge') {
          window.navigator.msSaveBlob(blob, name)
        } else {
          const a = document.createElement('a')
          const body = document.querySelector('body')
          a.download = name || 'image'
          a.href = URL.createObjectURL(blob)
          a.style.display = 'none'
          body.appendChild(a)
          a.click()
          body.removeChild(a)
          window.URL.revokeObjectURL(a.href)
        }
      })
    },

3.this.convertUrlToBase64(url)就是利用canvas和toDataURL把图片转成base64格式并返回

convertUrlToBase64 (url) {
      return new Promise((resolve, reject) => {
        const img = new Image()
        img.crossOrigin = 'Anonymous'
        img.src = url
        img.onload = function () {
          const canvas = document.createElement('canvas')
          canvas.width = img.width
          canvas.height = img.height
          const ctx = canvas.getContext('2d')
          ctx.drawImage(img, 0, 0, img.width, img.height)
          const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
          const dataURL = canvas.toDataURL('image/' + ext)
          const base64 = {
            dataURL: dataURL,
            type: 'image/' + ext,
            ext: ext
          }
          resolve(base64)
        }
      })
    },

其中:img.crossOrigin = 'Anonymous'是前端对图片的跨域处理;

4.this.convertBase64UrlToBlob(base64)是将图片base64流文件转成blob文件

convertBase64UrlToBlob (base64) {
      const parts = base64.dataURL.split('base64,')
      const contentType = parts[0].split(':')[1]
      const raw = window.atob(parts[1])
      const rawLength = raw.length
      const uInt8Array = new Uint8Array(rawLength)
      for (let i = 0; i < rawLength; i++) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      return new Blob([uInt8Array], { type: contentType })
    },

5.getBrowser()用来判断浏览器,解决浏览器兼容性问题:

import { getBrowser } from '@/utils/utils'
export function getBrowser () {
  const userAgent = navigator.userAgent
  if (userAgent.indexOf('OPR') > -1) {
    return 'Opera'
  }
  if (userAgent.indexOf('Firefox') > -1) {
    return 'FF'
  }
  if (userAgent.indexOf('Trident') > -1) {
    return 'IE'
  }
  if (userAgent.indexOf('Edge') > -1) {
    return 'Edge'
  }
  if (userAgent.indexOf('Chrome') > -1) {
    return 'Chrome'
  }
  if (userAgent.indexOf('Safari') > -1) {
    return 'Safari'
  }
}

6.如果是IE或者Edge浏览器,可以直接使用window.navigator.msSaveBlob(blob, name)完成下载;

声明:由于ios系统有安全性限制,以上方法在ios上无效;

以上就是记录项目中用到的图片下载,浏览器兼容的问题,涉及到的base64和blob的知识点和原理还不是很清晰,有时间一定要研究一下,整个方法,亲测有效;欢迎测用,与意见反馈。也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
详解纯CSS3制作的20种loading动效
Jul 05 HTML / CSS
不同浏览器对CSS3和HTML5的支持状况
Oct 31 HTML / CSS
详解CSS3中常用的样式【基本文本和字体样式】
Oct 20 HTML / CSS
HTML5打开本地app应用的方法
Mar 31 HTML / CSS
html5标记文字_动力节点Java学院整理
Jul 11 HTML / CSS
详解如何用canvas画一个微笑的表情
Mar 14 HTML / CSS
HTML5 CSS3新的WEB标准和浏览器支持
Jul 16 HTML / CSS
HTML5验证以及日期显示的实现详解
Jul 05 HTML / CSS
HTML块级标签汇总(小篇)
Jul 13 HTML / CSS
使用layui框架实现点击左侧导航切换右侧内容且右侧选项卡跟随变化的效果
Nov 10 HTML / CSS
web前端之css水平居中代码解析
May 20 HTML / CSS
CSS3实现指纹特效代码
Mar 17 HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
Jun 03 #HTML / CSS
详解利用canvas实现环形进度条的方法
Jun 12 #HTML / CSS
Html5 实现微信分享及自定义内容的流程
Aug 20 #HTML / CSS
前端canvas动画如何转成mp4视频的方法
Jun 17 #HTML / CSS
详解FireFox下Canvas使用图像合成绘制SVG的Bug
Jul 10 #HTML / CSS
canvas实现有递增动画的环形进度条的实现方法
Jul 10 #HTML / CSS
Html5新增标签与样式及让元素水平垂直居中
Jul 11 #HTML / CSS
You might like
如何对PHP程序中的常见漏洞进行攻击(下)
2006/10/09 PHP
虚拟主机中对PHP的特殊设置
2006/10/09 PHP
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
查找mysql字段中固定字符串并替换的几个方法
2012/09/23 PHP
PHP Reflection API详解
2015/05/12 PHP
Zend Framework教程之Zend_Layout布局助手详解
2016/03/04 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
IE6下通过a标签点击切换图片的问题
2010/11/14 Javascript
超级好用的jQuery圆角插件 Corner速成
2014/08/31 Javascript
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
jquery中获取元素里某一特定子元素的代码
2014/12/02 Javascript
JavaScript动态创建link标签到head里的方法
2014/12/22 Javascript
jquery常用函数与方法汇总
2015/09/01 Javascript
WebGL利用FBO完成立方体贴图效果完整实例(附demo源码下载)
2016/01/26 Javascript
Bootstrap和Java分页实例第一篇
2016/12/23 Javascript
angular中实现li或者某个元素点击变色的两种方法
2017/07/27 Javascript
浅谈es6语法 (Proxy和Reflect的对比)
2017/10/24 Javascript
详解NODEJS的http实现
2018/01/04 NodeJs
layer 刷新某个页面的实现方法
2019/09/05 Javascript
在Express中提供静态文件的实现方法
2019/10/17 Javascript
VuePress 中如何增加用户登录功能
2019/11/29 Javascript
JQuery省市联动效果实现过程详解
2020/05/08 jQuery
在vue中使用echarts(折线图的demo,markline用法)
2020/07/20 Javascript
jQuery实现容器间的元素拖拽功能
2020/12/01 jQuery
深入解析Python的Tornado框架中内置的模板引擎
2016/07/11 Python
python多进程控制学习小结
2018/10/31 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
中医药大学市场营销专业自荐信
2013/09/29 职场文书
中学家长会邀请函
2014/02/03 职场文书
学生期末评语大全
2014/04/30 职场文书
公开承诺书格式
2014/05/21 职场文书
高中同学会活动方案
2014/08/14 职场文书
公司欠款证明
2015/06/24 职场文书
MySQL时间盲注的五种延时方法实现
2021/05/18 MySQL
Python使用socket去实现TCP客户端和TCP服务端
2022/04/12 Python