利用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的文字阴影—text-shadow的使用方法
Dec 25 HTML / CSS
开发人员所需要知道的HTML5性能分析面面观
Jul 05 HTML / CSS
使用HTML5的链接预取功能(link prefetching)给网站提速
Dec 13 HTML / CSS
html5声频audio和视频video等新特性详细说明
Dec 26 HTML / CSS
html5配合css3实现带提示文字的输入框(摆脱js)
Mar 08 HTML / CSS
程序设计HTML5 Canvas API
Apr 08 HTML / CSS
使用phonegap播放音频的实现方法
Mar 31 HTML / CSS
HTML5 video 上传预览图片视频如何设置、预览视频某秒的海报帧
Aug 28 HTML / CSS
记一次高分屏下canvas模糊问题
Feb 17 HTML / CSS
HTML5实现应用程序缓存(Application Cache)
Jun 16 HTML / CSS
浅析HTML5页面元素及属性
Jan 20 HTML / CSS
html form表单基础入门案例讲解
Jul 15 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
深入解析phpCB批量转换的代码示例
2013/06/27 PHP
PHP模板引擎Smarty的缓存使用总结
2014/04/24 PHP
PHP读取RSS(Feed)简单实例
2014/06/12 PHP
php生成zip文件类实例
2015/04/07 PHP
php强大的时间转换函数strtotime
2016/02/18 PHP
Javascript 获取链接(url)参数的方法[正则与截取字符串]
2010/02/09 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
js继承call()和apply()方法总结
2014/12/08 Javascript
node.js中的fs.chmodSync方法使用说明
2014/12/18 Javascript
JS动态修改iframe内嵌网页地址的方法
2015/04/01 Javascript
Javascript的表单验证-揭开正则表达式的面纱
2016/03/18 Javascript
jQuery表单插件ajaxForm实例详解
2017/01/17 Javascript
JS实现中国公民身份证号码有效性验证
2017/02/20 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
基于Vue2.X的路由和钩子函数详解
2018/02/09 Javascript
搭建基于express框架运行环境的方法步骤
2018/11/15 Javascript
JavaScript中的null和undefined用法解析
2019/09/30 Javascript
Vue实现数据请求拦截
2019/10/23 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
[57:16]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第二场
2014/05/26 DOTA
在Django中创建URLconf相关的通用视图的方法
2015/07/20 Python
Pycharm编辑器技巧之自动导入模块详解
2017/07/18 Python
python中实现延时回调普通函数示例代码
2017/09/08 Python
python 以16进制打印输出的方法
2018/07/09 Python
浅谈Django的缓存机制
2018/08/23 Python
Python实现的文轩网爬虫完整示例
2019/05/16 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
南非最受欢迎的时尚品牌:MRP
2016/09/18 全球购物
汽车专业大学生职业生涯规划范文
2014/01/07 职场文书
俄罗斯商务邀请函
2014/01/26 职场文书
心理学专业求职信
2014/06/16 职场文书
煤矿安全生产月活动总结
2014/07/05 职场文书
黄埔军校观后感
2015/06/10 职场文书
2016元旦文艺汇演主持词
2015/07/06 职场文书
2016年幼儿园庆六一开幕词
2016/03/04 职场文书