问题背景 

微信公H5 使用input 多图上传的功能 , 安卓手机上只能一次上传一张图片

解决方案

使用 wx.chooseImage 上传拿到文件id (localId),再把文件id转为file文件,然后正常上传即可

以下代码已经过多台安卓/ios手机测试,上传正常 

// demo.tsx

import { wxChooseImage } from './upload';
<Button
  type='primary'
  onClick={() => {
    wxChooseImage().then((res) => {
      console.log(res);
      // res: ['http:xxx.jpg', http:yyy.jpg, ...]
    });
  }}>
  上传
</Button>;


// upload.ts
export function wxChooseImage() {
  return new Promise<File[]>((resolve, reject) => {
    wx.ready(() => {
      const rejectFn = (err: any) => {
        reject(err);
      };

      wx.chooseImage({
        count: 9,
        sizeType: ['original'],
        sourceType: ['album'],
        fail: rejectFn,
        success: function (res: { localIds: any }) {
          const localIds = res.localIds || [];
          if (localIds.length === 0) return;
          const resoveFn = (localId: string = localIds[0]): Promise<File[]> => {
            return new Promise((resolve) => {
              const fileArr = [];
              const getLocalImgData = (localId: string) => {
                wx.getLocalImgData({
                  localId,
                  success: async function (res: { localData: any }) {
                    let baseImage = res.localData;
                    if (baseImage.indexOf('data:image') !== 0) {
                      baseImage = 'data:image/jpeg;base64,' + baseImage;
                    }
                    baseImage = baseImage
                      .replace(/\r|\n/g, '')
                      .replace('data:image/jpg', 'data:image/jpeg')
                      .replace('data:image/JPG', 'data:image/jpeg');

                    fileArr.push(base64ToFile(baseImage));
                    if (fileArr.length === localIds.length) {
                      resolve(fileArr);
                    } else {
                      getLocalImgData(localIds[fileArr.length]);
                    }
                  },
                  fail: rejectFn
                });
              };
              getLocalImgData(localId);
            });
          };

          resoveFn().then(async (files) => {
            // 这里的files等同于通过input上传拿到的file,正常上传到后台服务器即可
            // 下面==内的代码是我们业务实际的上传代码,可以不用关注
            // ====================================================================================================
            // 压缩文件
            const newFiles = (await watermarkImg(files, '', { maxWidth: 1600, quality: 0.7 })) as File[];
            // 阿里oss上传
            api.base.oss.upload(newFiles).then((res) => {
              const result = [];
              res?.forEach((x: any, i: number) => {
                if (x.res?.status === 200) {
                  result.push( x.url);
                }
              });
              // 拿到结果展示在前端页面
              resolve(result);
            }, rejectFn);
            // ====================================================================================================
          }, rejectFn);
        }
      });
    });
  });
}

export function base64ToFile(urlData: string) {
  const arr = urlData.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bytes = atob(arr[1]); // 解码base64
  let n = bytes.length;
  const ia = new Uint8Array(n);
  while (n--) {
    ia[n] = bytes.charCodeAt(n);
  }
  return new Blob([ia], { type: mime });
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐