Ionic 3中如何通过Camera插件获取File对象并POST多文件?
我来帮你解决这个问题!要把Camera插件拿到的FILE_URI转换成标准File对象,然后批量发送,其实可以通过Cordova File插件或者Fetch API来实现,完全不用依赖只支持单张上传的FileTransfer。下面分两种方法详细说明:
方法一:使用Cordova File插件直接获取File对象
这个方法兼容性最好,能直接解析Camera返回的各种格式URI(比如content://、file://、cdvfile://),步骤如下:
- 先确保安装必要的插件:
cordova plugin add cordova-plugin-camera cordova plugin add cordova-plugin-file
- 调用相机并转换为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




