You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ionic 3中如何通过Camera插件获取File对象并POST多文件?

我来帮你解决这个问题!要把Camera插件拿到的FILE_URI转换成标准File对象,然后批量发送,其实可以通过Cordova File插件或者Fetch API来实现,完全不用依赖只支持单张上传的FileTransfer。下面分两种方法详细说明:


方法一:使用Cordova File插件直接获取File对象

这个方法兼容性最好,能直接解析Camera返回的各种格式URI(比如content://file://cdvfile://),步骤如下:

  1. 先确保安装必要的插件:
cordova plugin add cordova-plugin-camera
cordova plugin add cordova-plugin-file
  1. 调用相机并转换为File对象:
// 用于存储最终要上传的File对象数组
const uploadFiles = [];

// 调用相机拍摄/选择图片的函数
async function captureAndConvertImage() {
  try {
    // 获取图片的FILE_URI
    const imageUri = await navigator.camera.getPicture({
      quality: 50,
      destinationType: Camera.DestinationType.FILE_URI,
      sourceType: Camera.PictureSourceType.CAMERA, // 也可以改成PHOTOLIBRARY选择相册图片
      allowEdit: false,
      encodingType: Camera.EncodingType.JPEG
    });

    // 解析URI获取FileEntry对象
    const fileEntry = await new Promise((resolve, reject) => {
      window.resolveLocalFileSystemURL(imageUri, resolve, reject);
    });

    // 从FileEntry提取标准File对象
    const rawFile = await new Promise((resolve, reject) => {
      fileEntry.file(resolve, reject);
    });

    // 可选:自定义文件名(避免重名)
    const customFileName = `upload_photo_${Date.now()}.jpg`;
    const formattedFile = new File([rawFile], customFileName, { type: rawFile.type });

    // 添加到上传数组
    uploadFiles.push(formattedFile);
    console.log("已添加图片到上传队列:", formattedFile.name);
  } catch (error) {
    console.error("图片捕获/转换失败:", error);
  }
}

方法二:使用Fetch API将URI转Blob再包装成File

如果不想额外安装File插件,也可以用Fetch直接读取URI内容转成Blob,再包装成File对象:

const uploadFiles = [];

async function captureAndConvertImage() {
  try {
    const imageUri = await navigator.camera.getPicture({
      quality: 50,
      destinationType: Camera.DestinationType.FILE_URI,
      sourceType: Camera.PictureSourceType.CAMERA
    });

    // 处理不同平台的URI前缀(比如Android的file://)
    let fetchableUri = imageUri;
    if (fetchableUri.startsWith('file://')) {
      // Android环境下可能需要去掉file://前缀才能被Fetch访问
      fetchableUri = fetchableUri.replace('file://', '');
    }

    // 用Fetch获取图片Blob
    const response = await fetch(fetchableUri);
    const imageBlob = await response.blob();

    // 包装成标准File对象
    const fileName = `upload_photo_${Date.now()}.jpg`;
    const formattedFile = new File([imageBlob], fileName, { type: 'image/jpeg' });

    uploadFiles.push(formattedFile);
    console.log("已添加图片到上传队列:", formattedFile.name);
  } catch (error) {
    console.error("图片转换失败:", error);
  }
}

批量发送文件数组到服务器

不管用哪种方法得到File数组后,就可以用FormData封装,通过Fetch或Axios发送POST请求:

async function uploadBatch() {
  if (uploadFiles.length === 0) {
    console.log("没有待上传的图片");
    return;
  }

  const formData = new FormData();
  // 遍历文件数组,添加到FormData(字段名'files[]'要和服务器端接收的参数名对应)
  uploadFiles.forEach((file) => {
    formData.append('files[]', file, file.name);
  });

  try {
    const response = await fetch('https://你的服务器上传接口地址', {
      method: 'POST',
      body: formData,
      // 无需手动设置Content-Type,浏览器会自动添加正确的multipart/form-data边界
    });

    const result = await response.json();
    console.log("批量上传成功:", result);
    // 上传完成后可以清空数组
    uploadFiles.length = 0;
  } catch (error) {
    console.error("批量上传失败:", error);
  }
}

额外注意事项

  • 权限配置:确保在config.xml中添加了必要的权限,比如Android的相机、存储权限,iOS的相机访问描述。
  • 文件大小:可以通过Camera的quality参数调整图片质量,避免文件过大导致上传超时。
  • 平台兼容:如果遇到URI解析问题,优先选择方法一的File插件方案,兼容性更稳定。

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

火山引擎 最新活动