微信图片上传方案

4,725 阅读3分钟

微信图片上传方案

现在上线的方案为:

注册微信JSSDK -> wx.chooseImage 唤起相机选择图片 -> wx.uploadImage 上传图片至微信服务器 -> wx.downloadImage 图片下载到本地 -> wx.getLocalImgData 找到本地图片生成base64 -> base64转文件之后 调用我们的图片上传接口(baseSave.json) ->接口返回图片地址,拼接域名+/picture/+*** 展示图片

 //选择图片
    addImageMethod = (imageName) => {
        Toast.loading('唤起相机中,请稍等...', 2);
        changeImage = imageName;
        let that = this;
        //唤起相机
        wx.chooseImage({
            count: 1, // 默认9
            sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
            sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
            success: function (res) {
                Toast.hide();
                that.uploadFile(res.localIds);
            },
            fail: function (err) {
                Toast.hide();
                Modal.alert('警告', '请确保微信权限都已开启,不然无法正常调用相机功能', [
                    { text: '知道了', onPress: () => console.log('cancel') },
                ])
            }
        })
    }
    //上传图片
    uploadFile = (localIds) => {
        let that = this;
        wx.uploadImage({
            localId: localIds.toString(),
            success: function (data) {
                that.downloadImage(data.serverId)
            },
            fail: function (data) {
                Toast.info('上传图片失败,请联系客服', 2);
            }
        });
    }
    //下载图片接口
    downloadImage = (serverId) => {
        let that = this;
        wx.downloadImage({
            serverId: serverId, // 需要下载的图片的服务器端ID,由uploadImage接口获得
            isShowProgressTips: 1, // 默认为1,显示进度提示
            success: function (res) {

                var localId = res.localId; // 返回图片下载后的本地ID
                that.getLocalImgData(localId)
            },
            fail: function (data) {
                Toast.info('上传图片失败,请联系客服', 2);
            }
        })
    }
    //获取本地图片接口
    getLocalImgData = (serverId) => {
        let that = this;
        wx.getLocalImgData({
            localId: serverId, // 图片的localID
            success: function (res) {

                var localData = res.localData; // localData是图片的base64数据,可以用img标签显示
                that.uploadFileBase(res.localData)
            },
            fail: function (data) {
                Toast.info('上传图片失败,请联系客服', 2);
            }
        })
    }
    //上传图片到自己的服务器
    uploadFileBase = (base64Data) => {
        let blob = '';
        if (base64Data.indexOf("base64") > -1) {

            blob = this.dataURLtoBlob(base64Data);
        } else {

            blob = this.dataURLtoBlob("data:img/jpg;base64," + base64Data);
        }

        let file = this.blobToFile(blob, '123.jpg');

        let formdata = new FormData();
        formdata.append('file', file, '123.jpg');

        const url = '/upload/***';
        let that = this;
        Toast.loading('Loading...', 5);
        fetch(url, {
            method: 'POST',
            mode: 'cors',
            body: formdata,
            dataType: 'json',
        }).then(function (response) {
            return response.json();
        }).then(function (data) {
            Toast.hide()
            if (data.success) {
                Toast.info(data.message || '上传成功', 2);
                if (changeImage == 'image1') {
                    that.setState({
                        image1: "/picture/" + data.items[0]
                    })
                    imageData.image1 = "/picture/" + data.items[0];
                    sessionStorage.setItem('identityCard', JSON.stringify(imageData));
                } else {
                    that.setState({
                        image2: "/picture/" + data.items[0]
                    })
                    imageData.image2 = "/picture/" + data.items[0];
                    sessionStorage.setItem('identityCard', JSON.stringify(imageData));
                }
            } else {
                Toast.info(data.message || '上传失败', 2);
            }
        }).catch(error => console.log("error=" + error));
    }
    //将base64转换为blob
    dataURLtoBlob = (dataurl) => {
        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 Blob([u8arr], {
            type: mime
        });
    }
    //将blob转换为file
    blobToFile = (blob, fileName) => {
        blob.lastModifiedDate = new Date();
        blob.name = fileName;
        return blob;
    }

** 注意: base64在转blob时 因为wx返回的base64在安卓手机和IOS手机 不同:一个会有data:img/jpg;base64, 一个没有。所以需要进行处理后再转Bolb **

前端理想解决方案:

依然依赖微信JSSDK,因为微信已经做好了手机兼容性以及多选图片的功能与图片的压缩,安全性更高并且可以满足更多的业务需求。

注册微信JSSDK -> wx.chooseImage 唤起相机选择图片 -> wx.uploadImage 上传图片至微信服务器 -> 将图片ID传给后端,后端通过接口获取图片,下载到我们的服务器,然后返回图片在我们服务器的地址->返回下载成功

不依赖微信JSSDK,通过H5实现图片上传。

需要考虑各个手机,各个版本微信的兼容性。 H5选择图片 只支持单选。 需要考虑图片压缩问题