MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

React-Native开发鸿蒙NEXT-图片上传

2025-01-18 20:08 huorong 精选文章 4 ℃ 0 评论

之前在React-Native开发鸿蒙NEXT(5)

React-Native开发鸿蒙NEXT(5)

悬空八只脚,公众号:悬空八只脚React-Native开发鸿蒙NEXT(5)

里提到了鸿蒙下OSS上传的问题当时没有解决,后来解决了把这事忘记交代了,这里补充一下。后续关于React-Native开发鸿蒙NEXT一些技术输出不再以编号命名,基本会以技术点为标题便于查找,尽量多聊些干货

由于阿里云OSS没有HarmonyOS NEXT版本的SDK,只能使用web直传方式来实现RN端的图片上传,事实上阿里云对于HarmonyOS NEXT的最佳实践也是基于web直传来实现的。

(网址:

help.aliyun.com/zh/oss/use-…)

HarmonyOS NEXT的最佳实践help.aliyun.com/zh/oss/use-…

这里结合下实际项目来整体说明下图片上传流程。

图片的选取项目中使用的是react-native-image-picker

(网址:

gitee.com/react-nativ…)

react-native-image-pickerhttps://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/react-native-image-picker.md

实测发现如果相片高宽大于2000会出现报错的问题,最好限制一下尺寸

import {
  launchImageLibrary,
  launchCamera,
  ImageLibraryOptions,
  CameraOptions,
} from 'react-native-image-picker';
......

    // 测试最高宽高2000就会报500错误,这里用1500
    launchImageLibrary(
      {
        mediaType: 'photo',
        maxWidth: 1500,
        maxHeight: 1500,
        quality: 1,
        selectionLimit: 1,
      },
      .......

通过相机或者相片库返回的数据格式如下:

{
  "assets": [{
      "fileName": "screenshot_20240807_122206.jpg",
      "type": "jpg",
      "fileSize": 1467676,
      "originalPath": "file://media/Photo/1/IMG_1723004626_000/screenshot_20240807_122206.jpg",
      "height": 200,
      "width": 200,
      "uri": "/data/storage/el2/base/haps/entry/cache/rn_image_picker_lib_temp_a5421e0c-f687-4f76-9567-13147cc1a9bf.jpg"
  }]
}

上传必须用到的字段是fileName和uri。项目中图片的上传是基于调用后台接口做的Form表单提交,这里列举下Form的结构,去除了项目相关的业务内容

import FS from 'react-native-fs';
//上传
export async function upload(uri: string, fileName: string) {
  try {
    const filecontent = await FS.readFile(uri, 'base64');
    // convertBase64UrlToBlob(filecontent);

    const body = new FormData();
    // File64是后台业务定义的文件内容接收字段
    body.append('File64', filecontent);
    body.append('FileName', fileName);
    const options = {
      method: 'POST',
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      body,
    };
    const resp = await fetch(省略请求接口, options);
    const text = await resp.text();
    const json = JSON.parse(text);
    // 如果请求失败
    ...省略业务异常
    return json;
  } catch (e) {
    ...省略异常处理
  }
}

其中利用react-native-fs来根据uri获取文件内容。

(网址:

gitee.com/react-nativ…)

react-native-fshttps://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/react-native-fs.md

convertBase64UrlToBlob方法用来将获取到的base64格式文件内容转化为Blob,具体是否需要得看后台小伙伴的定义。网上查找到的资料转化后结果与基于在线转化的结果不一致,可以直接使用下面的方法。

function convertBase64UrlToBlob(base64: string) {
  try {
    let type = base64.split(',')[0].match(/:(.*?);/)[1];//提取base64头的type如 'image/png'
    let bytes = atob(base64.split(',')[1]);//去掉url的头,并转换为byte (atob:编码 btoa:解码)
    //处理异常,将ascii码小于0的转换为大于0
    //let ab = new ArrayBuffer(bytes.length);//通用的、固定长度(bytes.length)的原始二进制数据缓冲区对象
    let ia = new Uint8Array(bytes.length);
    for (let i = 0; i < bytes.length; i++) {
      ia[i] = bytes.charCodeAt(i);
    }
    let blob = new Blob([ia], {type: type});
    // console.log(blob);
    return blob;
  } catch (e) {
    ...省略异常处理
  }
}

建议将上传做成接口请求形式,避免暴露oss的accessKey和secret。


更多内容可关注\
我的公众号React-Native开发鸿蒙NEXT-图片上传

作者:悬空八只脚
链接:https://juejin.cn/post/7433304070969524262
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Tags:native2ascii

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言