Vant Uploader 文件上传手机上所遇到的坑

公司H5项目文件上传用到了Vant Uploader文件上传组件,但是这个组件的坑属实是真的多,写这篇文章给大家分享一下,如果问题和我同样的话就不用纠结了,可以直接换组件了~~

问题1:我在谷歌浏览器的模拟器中测试可以,为什么在手机上却没有办法显示,如下图
Vant Uploader 文件上传手机上所遇到的坑_第1张图片
这个问题总共是有2处坑

  1. 关乎公司所购买的服务器,图片上传是经过服务器上传的,如果你们公司购买的服务器很便宜,那么它的传输速度就会很慢,这会导致图片上传以后回显加载的很慢或者是直接不回显。
  • 解决方案:

    前端可以在图片上传前压缩图片,这类代码其他博客有很多,随便搜索下就有了,这里顺便也给大家贴出来,这里要注意,如果你使用过这个方法却失败了还是不行,有可能是因为你没有转换文件,与后端所需要的格式不一致,所以会导致失败

	//这里是把上传的文件转换
    dataURLtoFile(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 });
    }
  然后就是压缩图片大小
  if (/\/(?:jpeg|png)/i.test(event.file.type) && event.file.size > 500000) {
     
        // 创建Canvas对象(画布)
        let canvas = document.createElement("canvas");
        // 获取对应的CanvasRenderingContext2D对象(画笔)
        let context = canvas.getContext("2d");
        // 创建新的图片对象
        let img = new Image();
        // 指定图片的DataURL(图片的base64编码数据)
        img.src = event.content;
        // 监听浏览器加载图片完成,然后进行进行绘制
        img.onload = () => {
     
          // 指定canvas画布大小,该大小为最后生成图片的大小
          canvas.width = 400;
          canvas.height = 300;
          /* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
        如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/

          context.drawImage(img, 0, 0, 400, 300);
          // 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
          event.content = canvas.toDataURL(event.file.type, 0.92);
          let config = {
     
            headers: {
     
              //添加请求头
              "Content-Type": "multipart/form-data"
            }
          };
          let file = this.dataURLtoFile(event.content, "image");
          // console.log(file)
          let params = new FormData();

          params.append("file", file);
          let url = `这里写公司图片上传的接口`;
          this.$http({
     
            method: "POST",
            url: process.env.MOBILE_ROOT + url,
            data: params,
            config
          })
            .then(res => {
     
              if (res.code == 200) {
     
                this.fileList.push({
     
                  url: res.result.url
                });
                // Indicator.close();
              }
            })
            .catch(e => {
     });
        };
      } 

2.部分oppo,小米手机不支持这个组件,我自己实测了很多手机,例如苹果6,7,8,华为等等,在这些手机中oppo和小米部分型号手机是不支持Vant Uploader这个组件的,看到这里是不是欲哭无泪,辛辛苦苦大半天结果不兼容。。。

  • 解决方案:

    换另外的组件,比如说微信公用的api chooseImage(),这个方法是最合适,详细的使用方法可以去微信的开发文档里看,这里也把代码贴一下

	//先判断下终端是什么
    updateImg(style) {
     
      this.style = style;
      if (this.fromWhere == "wechat") {
     
        //上传图片
        this.chooseImage();
      } else if (this.fromWhere == "ios") {
     
        window.webkit.messageHandlers.uploadImage.postMessage({
      body: [] });
      } else if (this.fromWhere == "android") {
     
        window.native.uploadImage();
      }
    },
//然后可以设置上传时最多上传几张,压缩图以及相片来源
 chooseImage() {
     
      this.$wx.chooseImage({
     
        count: 1,
        sizeType: ["compressed"], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ["album", "camera"], // 可以指定来源是相册还是相机,默认二者都有
        success: res => {
     
          var localId = res.localIds[0]; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
          this.uploadImg(localId);
        }
      });
    },
//这里是获取图片上传后返回来的一个图片本地ID
    uploadImg(localId) {
     
      this.$wx.uploadImage({
     
        localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得
        isShowProgressTips: 1, // 默认为1,显示进度提示
        success: res => {
     
          let serverId = res.serverId;
          this.setServer(serverId);
        },
        fail: function(error) {
     
          Toast("上传错误,请稍候重试!");
        }
      });
    }
//最后上传图片并回显
  setServer(serverId) {
     
      var url = "这里写公司图片上传的接口";
      var formData = new FormData();
      formData.append("mediaId", serverId);
      this.$http({
     
        method: "POST",
        url: process.env.API_ROOT + url,
        data: formData
      })
        .then(res => {
     
          if (res.code == 200) {
     
            if (this.style == 1) {
     
              this.cardPositive = res.result;
              this.passPort = res.result;
              this.household = res.result;
            } else {
     
              this.cardBack = res.result;
            }
          }
        })
        .catch(e => {
     });
    },

总结:我太难了。。。(后续还有几个问题以后再写)

你可能感兴趣的:(javascript,js,vue)