您现在的位置是:首页 >技术杂谈 >react-native 文件上传的坑网站首页技术杂谈
react-native 文件上传的坑
简介react-native 文件上传的坑
需求:
1.通过画布或者其他的获取图片插件生成base64
2.base64转换file上传文件
1.图片插件生成base64
生成base64,可以通过一些插件会给你生成,自己需要生成的话可以使用 ReaderFile的readAsDataURL()来转换
var reader = new FileReader();
reader.readAsDataURL(inpFile.files[0]);
reader.onload = function () {
baseData = reader.result;
console.log("? ~ file: 图片:", baseData); //获取到base64格式图片
};
2.base64转换file
base64转换有多种方法,就不一一列出,直接上代码
import { Base64 } from 'js-base64'
/**
* 将base64转换为文件
* @param dataurl base64编码
* @param filename file name
* @returns
*/
export const dataURLtoFile = (base64Str: any, fileName: any) => {
const arr = base64Str.split(',')
const mime = arr[0].match(/:(.*?);/)[1] // base64解析出来的图片类型
const bstr = Base64.dencode(arr[1]) // 对base64串进行操作,去掉url头,并转换为byte atob为window内置方法
let len = bstr.length
const ab = new ArrayBuffer(len) // 将ASCII码小于0的转换为大于0
const u8arr = new Uint8Array(ab) //
while (len--) {
u8arr[len] = bstr.charCodeAt(len)
}
// 创建新的 File 对象实例[utf-8内容,文件名称或者路径,[可选参数,type:文件中的内容mime类型]]
return new File([u8arr], fileName, {
type: mime,
})
}
上面代码需要注意:针对base64解码,可以使用 atob() 方法来进行解码,但这是window方法,在react-native不起作用。可以使用 js-base64 插件来代替。
3.上传文件
上传接口根据自己接口来判断
// result 是小编当前使用的签名插件 react-native-signature-capture
// 会返回参数 {encoded: base64编码, pathName: 文件路径}
_onSaveEvent = async (result: any) => {
const fd = new FormData()
// base64转换file
const file = dataURLtoFile(
`data:image/png;base64,${result.encoded}`,
`signature_${Date.now()}.png`,
)
fd.append('file', file)
// 调用接口
const dataFileUrl = await this.props.handleFileUrl(fd)
const tokenUrl = await this.props.addSasTokenOnUrl(dataFileUrl.url)
console.log('? ~ 上传文件 === ', dataFileUrl)
console.log('? ~ 下载文件 === ', tokenUrl)
....
}
4.上传报错
这个报错真的让我这个菜鸟头晕,但我经过三天三夜的战斗才发现一点问题,一点!!
在web使用new File()生成新的文件类型打印输出是没问题,但是在react-native输出出来的是类似于object的类型,所以导致文件上传缺失,不成功
解决方法:
生成新的文件类型并添加
// result 是小编当前使用的签名插件 react-native-signature-capture
// 会返回参数 {encoded: base64编码, pathName: 文件路径}
_onSaveEvent = async (result: any) => {
// 文件类型
const file = {
uri: result.pathName,
type: 'multipart/form-data',
name: `signature_${Date.now()}.png`,
}
const fd = new FormData()
// base64转换file
// const file = dataURLtoFile(
// `data:image/png;base64,${result.encoded}`,
// `signature_${Date.now()}.png`,
// )
fd.append('file', file)
// 调用接口
const dataFileUrl = await this.props.handleFileUrl(fd)
const tokenUrl = await this.props.addSasTokenOnUrl(dataFileUrl.url)
console.log('? ~ 上传文件 === ', dataFileUrl)
console.log('? ~ 下载文件 === ', tokenUrl)
....
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。