You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo 49下React Native移动端及Web端Cloudinary视频上传问题求解

问题分析与解决方案

核心问题

  1. 移动端返回undefined:你错误地对Expo ImagePicker返回的本地文件URI执行split(',')[1]操作——移动端的URI是file://开头的本地路径,并非base64格式,split后会得到undefined,导致上传的文件无效。
  2. Web端Bad Request:Web端返回的URI是带data:video/mp4;base64,前缀的完整base64字符串,你去掉前缀后,Cloudinary无法识别文件格式,从而返回400错误。
  3. FormData构造错误:跨平台上传视频时,移动端和Web端需要不同的文件格式处理逻辑,你当前的传参方式不兼容两端。

修正后的代码

1. 视频选择函数 pickVideo

const pickVideo = async () => {
  try {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Videos,
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      const asset = result.assets[0];
      // 直接使用原始URI,不做split操作
      const uri = await postToCloundinaryVideo(asset);
      console.log('上传完成,返回URL:', uri);
    }
  } catch (err) {
    console.error('视频选择或上传失败:', err);
  }
};

2. Cloudinary上传函数 postToCloundinaryVideo

import { Platform } from 'react-native';

const postToCloundinaryVideo = async (asset) => {
  const formData = new FormData();
  let file;

  // 区分平台处理文件
  if (Platform.OS === 'web') {
    // Web端:将base64 URI转为Blob(标准上传方式)
    const blob = await fetch(asset.uri).then(res => res.blob());
    file = blob;
  } else {
    // 移动端:构造符合FormData要求的文件对象
    file = {
      uri: asset.uri,
      name: `video_${Date.now()}.mp4`,
      type: asset.mimeType || 'video/mp4',
    };
  }

  formData.append('file', file);
  formData.append('upload_preset', 'my_value');
  formData.append('cloud_name', 'my_cloud_name');

  const response = await fetch(`https://api.cloudinary.com/v1_1/my_cloud_name/video/upload`, {
    method: 'POST',
    body: formData,
    // 不要手动设置Content-Type,浏览器/Expo会自动生成正确的multipart/form-data头
  });

  const data = await response.json();
  if (!response.ok) {
    throw new Error(data.error?.message || '上传失败');
  }
  return data.url;
};

额外注意事项

  • 确认你的Cloudinary上传预设(upload_preset)为未签名状态,且允许上传视频类型。
  • 移动端测试时,确保应用已获取媒体文件读取权限(Expo ImagePicker会自动请求,也可在app.json中显式声明权限)。
  • Web端若不想转Blob,也可直接传入完整的base64 URI(即asset.uri),Cloudinary同样支持该方式。

内容的提问来源于stack exchange,提问作者Charlie_57

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:42:41