React用fetch向后台传输Blob,File
1.Base64是什么
Base64一般用于在HTTP协议下传输二进制数据,Base64是一种用64个字符来表示任意二进制数据的方法。因此需要用6bit来表示字符(2的6次方=64),然而ASCII码需要8个Bit来表示,6个Bit不能存储8个Bit的数据,但是4x6个Bit可以存储3x8个Bit的数据。
2.如何获取Base64
当用input标签上传文件的时候,input.files[0]为上传的文件对象,也就是File数据,之后调用js的FileReader的readAsDataURL(file)来读取文件,在读取文件完毕的回调函数中可以获得文件的base64码。通过antDesign的Upload组件获取base64码。代码如下。其中base64Url为最终获取的base64码
beforeUpload(file, fileList) {
var reader = new FileReader();
const image = new Image();
var height;
var width;
var base64Url;
//因为读取文件需要时间,所以要在回调函数中使用读取的结果
reader.readAsDataURL(file); //开始读取文件
reader.onload = (e) => {
image.src = reader.result;
image.onload = () => {
height = image.naturalHeight;
width = image.naturalWidth;
base64Url= e.target.result, //cropper的图片路径
}
}
return false;
}
获取了base64码了之后主要就是进行截图,获取图片长宽等操作,最后再将base64转换成Blob,File格式传给后台,或者直接传给后台。
控制台打印base64
当将base64传给后台的时候,将base64码转换为Json然后传递到后台,请求头如下所示参数就是将base64码序列化成json字符串传递到后台
3.Base64转换成Blob
将Base64转换成Blob的代码如下
convertBase64UrlToBlob(base64Data) {
var byteString;
if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]);
} else {
byteString = unescape(base64Data.split(',')[1]);
}
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: this.state.selectImgSuffix });
}
控制台打印Blob
4.Base64转换成FILE
File 接口基于Blob,继承 blob功能并将其扩展为支持用户系统上的文件,将Base64转换成FILE的代码如下
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
控制台打印FILE
将文件以FILE的格式传递给后台,直接将File封装到formdata里面去,然后通过fetch发送给后台,dataURLtoFile()参数是base64和文件名,返回FILE。
saveImg() {
const { dispatch } = this.props;
var formdata = new FormData();
formdata.append("files", this.dataURLtoFile(this.state.srcBase64, this.state.selectImgName));
dispatch({
type: 'getData/postimage',
payload: formdata
});
}
当一个 Blob 或 File 被作为formdata .append()的第二个参数的时候, Blob 对象的默认文件名是 “blob”。 File 对象的默认文件名是该文件的名称 ,如果你指定一个 Blob 或者File作为数据添加到 FormData 对象中, 文件名会被放在 “Content-Disposition” 头部(常常会根据浏览器变化而变化)传给服务器,传输过程中请求头如下。可以在Content-Disposition中看见文件名称。下图为传输File向后台的时候的头文件,Content-Dispotion中可以看见filename为上传的文件名。
下图为传输Blob向后台的时候的头文件,Content-Dispotion中可以看见filename为blob。