Ionic 6中使用Fetch上传图片失败:无法向服务器发送图片数据
解决Ionic 6中Fetch无法发送图片数据的问题
直接将file://路径字符串添加到FormData是无效的,FormData要求传入File或Blob对象而非路径字符串。以下是具体解决方案:
核心步骤
- 读取本地图片文件内容,转换为Blob对象
- 将Blob对象添加到FormData后发送请求
方案一:使用Capacitor Filesystem插件(推荐)
1. 安装插件
npm install @capacitor/filesystem
2. 完整代码实现
import { Filesystem } from '@capacitor/filesystem'; async uploadAvatar(pathImage: string, token: string) { try { // 移除file://前缀,适配Capacitor文件路径规则 const filePath = pathImage.replace('file://', ''); // 读取文件内容(默认返回base64格式) const fileData = await Filesystem.readFile({ path: filePath }); // 将base64转为Blob对象 const blob = this.base64ToBlob(fileData.data, 'image/jpeg'); // 构建FormData并添加Blob(第三个参数为可选文件名) const formData = new FormData(); formData.append('photo', blob, 'avatar.jpg'); // 发送POST请求 const response = await fetch(`${this.MAIN_URL}/uploadAvatar?token=${token}`, { method: 'POST', body: formData }); const data = await response.json(); alert(JSON.stringify(data)); } catch (error) { alert(JSON.stringify(error)); } } // 辅助函数:base64转Blob private base64ToBlob(base64: string, contentType: string): Blob { const byteChars = atob(base64); const byteArrays: Uint8Array[] = []; for (let offset = 0; offset < byteChars.length; offset += 512) { const slice = byteChars.slice(offset, offset + 512); const byteNums = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNums[i] = slice.charCodeAt(i); } byteArrays.push(new Uint8Array(byteNums)); } return new Blob(byteArrays, { type: contentType }); }
方案二:使用Ionic Native File插件
1. 安装插件
npm install @ionic-native/file ionic cap sync
2. 代码实现
import { File } from '@ionic-native/file/ngx'; constructor(private file: File) {} async uploadAvatar(pathImage: string, token: string) { try { // 拆分文件路径和文件名 const path = pathImage.substring(0, pathImage.lastIndexOf('/') + 1); const fileName = pathImage.substring(pathImage.lastIndexOf('/') + 1); // 直接读取文件为Blob对象 const blob = await this.file.readAsBlob(path, fileName); // 构建FormData并发送请求 const formData = new FormData(); formData.append('photo', blob, fileName); const response = await fetch(`${this.MAIN_URL}/uploadAvatar?token=${token}`, { method: 'POST', body: formData }); const data = await response.json(); alert(JSON.stringify(data)); } catch (error) { alert(JSON.stringify(error)); } }
注意事项
- 权限配置:Android端需在
android/app/src/main/AndroidManifest.xml中添加文件读取权限:<!-- Android 12及以下 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> - 服务器端校验:确保服务器正确处理
multipart/form-data类型请求,能够接收photo字段的文件数据。
内容的提问来源于stack exchange,提问作者Roddy P. Carbonell
相关产品推荐
相关产品推荐

