react native(expo)选择图片/视频并上传阿里云oss

1.引入相关库:

@ant-design/react-native ant风格UI库
expo-file-system 文件访问
expo-image-picker 图片/视频选择器

2.新建图片选择并上传的帮助类

import { Toast } from '@ant-design/react-native';
import * as FileSystem from "expo-file-system";
import * as ImagePicker from 'expo-image-picker';
import AppService from "../api/app";
import Loading from "../components/ui/Loading";
import LogUtil from "./log_util";

// 从后端api获取
export let ossUrl = 'https://oss-2008.oss-cn-hongkong.aliyuncs.com';
let ossConfig = null;

/**
 * @desc 选择相册图片
 */
export const pickImage = async (mediaTypes = ImagePicker.MediaTypeOptions.Images) => {
    // No permissions request is necessary for launching the image library
    let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: mediaTypes,
        allowsEditing: true,
        aspect: null,
        quality: 0.5,
    });

    LogUtil.log('pick image result = ', result);

    if (result.canceled) {
        return null;
    }
    if (mediaTypes === ImagePicker.MediaTypeOptions.Images) {
        if (result.assets[0]?.fileSize/(1024*1024) > 2) {
            Toast.fail('图片不能超过2MB');
            return null;
        }
    } else if (mediaTypes === ImagePicker.MediaTypeOptions.Videos) {
        if (result.assets[0]?.fileSize/(1024*1024) > 10) {
            Toast.fail('视频不能超过10MB');
            return null;
        }
    } else {}

    return result.assets[0].uri;
};

export const uploadImage = async (fileName, filePath, nav) => {
    Loading.show();
    // 从后端获取阿里云oss相关凭证
    const res = await AppService.getAliyunOssToken({}, nav);
    if (res.code === 200) {
        /*
        *
        * host = obj['host']
            policyBase64 = obj['policy']
            accessid = obj['accessid']
            signature = obj['signature']
            expire = parseInt(obj['expire'])
            callbackbody = obj['callback']
            key = obj['dir']
        *
        *  */
        ossConfig = res.data;
        ossUrl = ossConfig['host'];
    } else {
        Loading.hide();
        Toast.info('获取oss token信息失败')
        return null;
    }

    if (filePath && filePath.length > 0) {
        const split = filePath.split('.');
        let realFileName = (!fileName || fileName.length === 0) ? `${random_string()}.${split[split.length - 1]}` : `${fileName}.${split[split.length - 1]}`;
        let key = `${ossConfig['dir']}${realFileName}`;
        let imageServicePath = `${ossConfig['host']}/${key}`;

        try {
            LogUtil.log('ossUrl = ', ossUrl)
            // 使用FileSystem.uploadAsync上传文件至阿里云oss
            const response = await FileSystem.uploadAsync(`${ossUrl}`, filePath, {
                fieldName: 'file',
                httpMethod: 'POST',
                uploadType: FileSystem.FileSystemUploadType.MULTIPART,
                parameters: {
                    'name': realFileName,
                    'key': key,
                    'policy': ossConfig['policy'],
                    'OSSAccessKeyId': ossConfig['accessid'],
                    'success_action_status': '200',
                    'callback': ossConfig['callback'],
                    'signature': ossConfig['signature']
                }
            })

            LogUtil.log('response', JSON.stringify(response), 'imageServicePath', imageServicePath)
            Loading.hide();
            if (response.status !== 200) {
                return null;
            }
            return { imageServicePath, fileName: key };
        } catch (error) {
            LogUtil.error(error)
        }
    }
    Loading.hide();
    return null;
}

const random_string = (len) => {
    len = len || 32;
    let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    let maxPos = chars.length;
    let pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

3.代码中调用:

3.1 只选择图片、视频后用于展示

pickImage(mediaTypes).then(uri => {
            if (uri) {
                // uri可直接使用ImageView组件展示
            }
        })

3.2 选择图片、视频再上传阿里云oss后展示

    const ChatTypes = {
        voice: 6,
        image: 2,
        video: 3,
        text: 1,
        systemTips: 4,
        autoText: 5,
    }    
    
    let imageSendValue = '';
    let videoSendValue = '';
    let imageUri = '';
    let videoUri = '';
    const pickAndUploadImage = (type) => {
        let mediaTypes = type === ChatTypes.image ? ImagePicker.MediaTypeOptions.Images : ImagePicker.MediaTypeOptions.Videos;
        pickImage(mediaTypes).then(uri => {
            if (uri) {
                uploadImage(null, uri, navigation).then(res => {
                    if (!res) {
                        Toast.info(i18n.t("Chat.UploadFail"));
                        return;
                    }
                    LogUtil.log('imageServicePath = ', res?.imageServicePath, 'fileName = ', res?.fileName)

                    switch (type) {
                        case ChatTypes.image:
                            imageSendValue = res?.fileName;
                            imageUri = uri;
                            // sendMessage(ChatTypes.image, imageSendValue, imageUri);
                            break;
                        case ChatTypes.video:
                            videoSendValue = res?.fileName;
                            videoUri = uri;
                            // sendMessage(ChatTypes.video, videoSendValue, videoUri);
                            break;
                        default:
                            break;
                    }
                })
            }
        })
    }
相关推荐
小池先生8 小时前
阿里云子账号管理ECS权限配置全指南
服务器·阿里云·云计算
banjin8 小时前
免费体验,在阿里云平台零门槛调用满血版DeepSeek-R1模型
阿里云·自然语言处理·云计算·ai编程·ai写作·deepseek
王会举8 小时前
DeepSeek模型集成到java中使用(阿里云版)超简单版
java·阿里云·deepseek
南望无一11 小时前
React Native 0.70.x如何从本地安卓源码(ReactAndroid)构建
前端·react native
小刘不知道叫啥11 小时前
React源码揭秘 | 启动入口
前端·react.js·前端框架
facaixxx202415 小时前
阿里云SLB负载均衡的ALB和NLB有啥区别?一个是7层一个是4层
阿里云·云计算·负载均衡
程序员小续18 小时前
Excel 表格和 Node.js 实现数据转换工具
前端·javascript·react.js·前端框架·vue·excel·reactjs
天上掉下来个程小白21 小时前
案例-22.配置文件-@ConfigurationProperties
spring boot·后端·阿里云
Eamonno1 天前
深入理解React性能优化:掌握useCallback与useMemo的黄金法则
react.js·性能优化
成长的小牛2332 天前
阿里云k8s服务部署操作一指禅
阿里云·kubernetes·云计算