关于vue移动端下载图片

最近在做一个vue移动端的项目,设计技术为vue2+vue相关+vant-ui+less,搭配浙里办Bridge插件。也算是几年来第一次做移动端相关的项目了,在做的过程中,记录下几个问题,一起分享下我的解决方式。

下载图片

在项目中有两处下载图片功能,一处为将base64格式的二维码图片下载到本地,一处为将html页面生成图片下载到本地。在最开始做的时候,我没想到手机端会有问题,直接按照pc浏览器上下载文件的方式去完成的,效果也出来了。

PC浏览器下载图片

pc端下载的原理还是比较易于理解的,将base64格式的图片转化为blob对象,再利用document对象创建一个a标签,通过点击方法实现图片下载,代码如下(代码非原创):

downloadFile(url){
  let aLink = document.createElement('a');
  let blob = this.base64ToBlob(url); //new Blob([content]);
  let evt = document.createEvent("HTMLEvents");
  console.log("点击下载",evt)
  evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
  aLink.download = 'xxx.png';
  aLink.href = URL.createObjectURL(blob);
  aLink.click()
},
base64ToBlob(code) {
  let parts = code.split(';base64,');
  console.log(parts);
  let contentType = parts[0].split(':')[1];
  let raw = window.atob(parts[1]);
  let rawLength = raw.length;
  let uInt8Array = new Uint8Array(rawLength);
  for (let i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }
  return new Blob([uInt8Array], {type: contentType});
}

这样子,PC上的效果是出来了,点击下载按钮执行方法后可以把图片下载到电脑上,但是没想到等项目到真机测试的时候,点击下载按钮是没有效果的。
真的是一头雾水,pc上还好好的,手机上咋就不行了呢!
最开始以为是方法不对,在网站上一顿搜索,试遍了找到的各种方法,还是没有用。又以为是手机端浏览器的问题,装了vconsole去查看手机端浏览器信息,也没有发现有啥异常的地方。
最后在SegmentFault思否网站上的一个贴子力看到了类似的问题,有人在下边评论里说了一句:手机端浏览器禁止下载base64格式的文件,这才明白过来。
下面的回复也有人说没发现有解决方案,最后和产品经理商量后被迫砍掉了下载功能。我是真的佩服!!!
因为项目里要使用浙里办插件,里面有完整的下载图片的API,但文档里也是特备注明了只支持下载网络资源图片。
综合以上信息:

  • 手机端浏览器可以生成base64文件但不能下载
  • 浙里办API可以下载网络资源图片

好比是金箍棒,两头都是好的,就中间部分断了,该怎么接上呢?
重点就是如何才能把base64文件转成网络资源图片?
当时项目已经做了大半,前期的功能已经比较完善了,后端提供的上传接口是File文件格式,提交数据时候需要使用FormData对象包裹起来,那如果我把base64格式文件转成File格式对象,上传到服务器之后拿到网路资源地址,不就可以下载了吗?
说干就干,网上一搜索,还真的有把base64转成File对象的方法。

移动端下载图片
  • 最初找到的方法
/* 分为两步:
 * 1.base64转为blob对象,
 * 2.blob对象转为file对象
 */
baseToBlob(url) {
  var arr = url.split(',');
  var mime = arr[0].match(/:(.*?);/)[1];
  var bstr = atob(arr[1]);
  var n = bstr.length;
  var u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
},
blobToFile(theBlob, fileName){
	let files = new File([theBlob], fileName, {type: 'image/jpeg'})
	theBlob.lastModifiedDate = new Date();
	theBlob.name = fileName;
	return files;
},

这样解决办法有很多帖子都是这么写的,可能适用于他们的情况,但无语我这里确是不行。因为上传接口的规定是必须是File格式的对象,依照以上代码转换出来的对象依旧是Blob格式,上传失败。

又在经历了很长时间的搜索之后,我突然发现了一个文章上的不同点,在baseToBlob方法的最后一行代码中可以将new Blob直接改为new File。那种感觉怎么说呢?就是你可以预想到这个一定是正确的,哈哈

果然,一试就成功上传,拿到了网络资源的地址。

  • 修改后的方法
downloadFile(){
  let content = this.qrCode;
  let blob = this.dataURLtoBlob(content,'二维码.png'); 
  let formData = new FormData()
  formData.append("file",blob)
  upload(formData).then(res=>{
    let {data} = res.data
    if(data && data.url){
      // xxx
    }
  })
},
dataURLtoBlob: function(dataurl,fileName) { 
    var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr],fileName, { type: mime });
},

功能顺利完成,虽然经过上传接口过了一手,下载完成的速度有点慢,但是功能效果是完好的。各位有缘能看到文章的大佬们,能在评论区说下你们是怎么解决移动端下载base64图片的问题吗?欢迎来访啊

Vue移动端应用中,如果需要用户从服务器下载图片到iOS设备,可以采用以下步骤: 1. **设置`<a>`标签**:创建一个`<a>`元素,并为其设置`href`属性指向图片资源URL,同时添加`download`属性以便触发下载操作。 ```html <a :href="imageUrl" @click="downloadImage">点击下载</a> ``` 其中,`imageUrl`是你要下载图片链接。 2. **定义下载方法**:在Vue组件内,创建一个`downloadImage`方法,处理点击事件并确认是否在iOS上下载。由于浏览器的安全限制,在iOS Safari中,直接点击`<a>`标签不会自动触发下载,需要额外处理。 ```javascript methods: { downloadImage(e) { e.preventDefault(); // 阻止默认的行为,防止跳转 const link = document.createElement('a'); link.href = this.imageUrl; link.download = this.fileName; // 图片文件名,可根据需求自定义 document.body.appendChild(link); // 将链接添加到DOM中 if (window.navigator.userAgent.includes('iPod')) { // 对于iOS设备,模拟点击 link.click(); setTimeout(() => { document.body.removeChild(link); }, 0); } else { link.click(); // 对非iOS设备,正常点击即可 } }, } ``` 3. **注意兼容性**:上述代码假设iOS设备支持`document.createRange().createContextualFragment()`, 这种情况下的下载。对于一些较旧的版本或特殊情况,可能需要进一步的判断和处理。 4. **处理异步回调**:下载操作通常是异步的,如果需要获取下载状态或进度信息,你需要监听`progress`事件或其他适合的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端SkyRain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值