利用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 相关文章推荐
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
Apr 16 HTML / CSS
任意一块网页内容实现“活”的背景(目前火狐浏览器专有)
May 07 HTML / CSS
谈谈对css属性box-sizing的了解
Jan 04 HTML / CSS
css3实现多个元素依次显示效果
Dec 12 HTML / CSS
HTML5拖放功能_动力节点Java学院整理
Jul 13 HTML / CSS
详解Canvas事件绑定
Jun 27 HTML / CSS
html5触摸事件判断滑动方向的实现
Jun 05 HTML / CSS
基于HTML5 audio元素播放声音jQuery小插件
May 11 HTML / CSS
HTML5实现获取地理位置信息并定位功能
Apr 25 HTML / CSS
HTML5 Canvas玩转酷炫大波浪进度图效果实例(附demo)
Dec 14 HTML / CSS
HTML5声音录制/播放功能的实现代码
May 03 HTML / CSS
使用CSS实现小三角边框原理解析
Nov 07 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 版获取重定向后的地址(代码)
2013/06/26 PHP
php读取大文件示例分享(文件操作类)
2014/04/13 PHP
php快速查找数据库中恶意代码的方法
2015/04/01 PHP
laravel利用中间件做防非法登录和权限控制示例
2019/10/21 PHP
java script编程起步(第三课)
2007/01/10 Javascript
jQuery textarea的长度进行验证
2009/05/06 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
2013/12/03 Javascript
中止javascript执行的方法
2014/02/14 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(jquery)
2014/11/16 Javascript
JavaScript中自定义事件用法分析
2014/12/23 Javascript
Javascript动态创建div的方法
2015/02/09 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
Bootstrap3 图片(响应式图片&amp;图片形状)
2017/01/04 Javascript
Vue2.x中的父子组件相互通信的实现方法
2017/05/02 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
Vuejs 实现简易 todoList 功能 与 组件实例代码
2018/09/10 Javascript
Koa日志中间件封装开发详解
2019/03/09 Javascript
一文了解Vue中的nextTick
2019/05/06 Javascript
Vue将页面导出为图片或者PDF
2020/08/17 Javascript
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
Python实现的多线程端口扫描工具分享
2015/01/21 Python
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
Linux CentOS7下安装python3 的方法
2018/01/21 Python
python海龟绘图之画国旗实例代码
2020/11/11 Python
Canvas引入跨域的图片导致toDataURL()报错的问题的解决
2018/09/19 HTML / CSS
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
巴西图书和电子产品购物网站:Saraiva
2017/06/07 全球购物
浅谈react路由传参的几种方式
2021/03/23 Javascript
中专生毕业个人鉴定
2014/02/26 职场文书
就业意向书范文
2014/04/01 职场文书
小学清明节活动总结
2014/07/04 职场文书
房屋所有权证明
2014/10/20 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
谁动了我的奶酪读书笔记
2015/06/30 职场文书
2016年圣诞节寄语(一句话)
2015/12/07 职场文书