React Native 中的上传
最近做了上传图片到服务端,其实不用第三方模块。
窝建议直接和 web 端一样采用 multipart/form-data
来上传,这样 APP 端和 web 端用的接口可以通用,至于将图片编码成 base64,再到服务端解码保存也是可以的,且效率差别也不是很大。但是由于要改服务端的逻辑,我就懒得用这个方法了。
如果仅从应用层观察,base64 是会按 4/3 比例增加传输成本。
但实际操作上,物理层和 MAC 层协议本身是有做压缩和冗余,所以用 base64,至少在这两层上讲,传输成本并不会按照 4/3 比例增多,传输效率可能和纯二进制序列传输没什么区别。
单文件
let formData = new FormData();
let params = {
uploadImg: {
uri: uri,
type: 'application/octet-stream',
name: 'image.jpg'
}
};
for (let key in params) {
formData.append(key, params[key]);
}
fetch('https://api.domain.com/upload.json', {
body: formData,
method: 'post',
headers: {
'Auth-Token': 'XXXXX'//php端直接用$_SERVER['HTTP_AUTH_TOKEN]接收
}
}).then((response) => {
console.log(response);
});
文件数组
PHP 可以直接用文件数组批量上传文件
<input type="file" name="image[]" />
<input type="file" name="image[]" />
<input type="file" name="image[]" />
<input type="file" name="image[]" />
<input type="file" name="image[]" />
然而我尝试在 RN 中也构造类似的结构却不行:
let params = {
'uploadImg[]': {
uri: uri,
type: 'application/octet-stream',
name: 'image.jpg'
},
'uploadImg[]': {
uri: uri,
type: 'application/octet-stream',
name: 'image.jpg'
}
};
于是按照 java web 里的类似方式构造是可以的:
let params = {
'uploadImg[0]': {
uri: uri,
type: 'application/octet-stream',
name: 'image.jpg'
},
'uploadImg[1]': {
uri: uri,
type: 'application/octet-stream',
name: 'image.jpg'
}
};
嫌麻烦的话使用 for 循环构造一下即可
最后总结一下 RN 中有关图片的第三方包 (也是踩坑过程中碰到的 (。・ω・。))
- react-native-image-picker 图片选取组件,但是不支持多选,裁剪功能不完善,窝现在只用到了它的照相功能,选取需要结合 react-native-image-crop-picker
- react-native-image-crop-picker 和上面的类似,但是它支持多选和裁剪,然而不支持照相,所以…
- react-native-image-resizer 这个主要用来压缩图片,一般 iOS 和 Android 拍摄出来的图片都有 3~5MB 左右,所以上传前压缩下当然是极好的