1. 思路
- 将
base64
格式的图片处理为Blob
对象。 - 将
Blob
对象添加到formData
对象中。 http
请求头设置为context-type: multipart/form-data
上送到文件服务器。
2. 将base64
图片转为Blob
对象。
-
分隔
base64
编码串。将开头的文件类型和后面的编码分开。如下图:
-
正则匹配获取文件类型:
image/jpeg
。 -
window.atob()
解析base64
编码,charCodeAt
转为UTF-16
的ASCII
,创建数组,将ASCII
放进去。当打印arrayBuffer
后你会发现,里面有Uint8Array
私有属性,并且该对象里面有对应的ASCII
值,如下图
new Blob
传入处理好的含有ASCII
的数组。
代码实现:
function base64ToBlob(base64Data) {
const dataArr = base64Data.split(','); // 根据,来分隔
const imageType = dataArr[0].match(/:(.*?);/)[1]; // 获取文件类型。使用正则捕获 image/jpeg
const textData = window.atob(dataArr[1]); // 使用atob() 将base64 转为文本文件
const arrayBuffer = new ArrayBuffer(textData.length); // 创建一个二进制数据缓冲区,可以理解为一个数组
const uint8Array = new Uint8Array(arrayBuffer); // 创建一个类型化数组对象,可以理解为上面的数组的成员,给这个对象赋值就会放到上面的数组中。
for(let i = 0; i < textData.length; i++) {
uint8Array[i] = textData.charCodeAt(i); // 将文本文件转为UTF-16的ASCII, 放到类型化数组对象中
}
return [new Blob([arrayBuffer], { type: imageType }), imageType.slice(6)]; // 返回两个值,一个Blob对象,一个图片格式(如jpeg)
}
3. 将Blob
对象添加到formData
对象中
new FormData
,传入处理好的blob
使用append
方法添加表单
代码实现
function toFormData(base64Data) {
const [imageBlob, imageType] = base64ToBlob(base64Data); // 获取处理好的Blob 和文件类型
const formData = new FormData();
formData.append('file', imageBlob, `${Date.now()}.${imageType}`); // 添加到表单,传入文件名
return formData;
}
4. http
请求头设置为context-type: multipart/form-data
上送到文件服务器
直接上代码
import axios from 'axios'; // 使用的是axios
// 上传到照片服务器
function httpRequest(formData) {
return axios({
method: 'post',
url: '', // 你的文件服务器地址
data: formData,
timeout: 60000,
headers: {
'Content-Type': 'multipart/form-data', // 请求头要设置为 form-data
'Cache-Control': 'no-cache',
},
});
}
5. 完整代码
import axios from 'axios'; // 使用的是axios
// base64 转为Blob
function base64ToBlob(base64Data) {
const dataArr = base64Data.split(','); // 根据,来分隔
const imageType = dataArr[0].match(/:(.*?);/)[1]; // 获取文件类型。使用正则捕获 image/jpeg
const textData = window.atob(dataArr[1]); // 使用atob() 将base64 转为文本文件
const arrayBuffer = new ArrayBuffer(textData.length); // 创建一个二进制数据缓冲区,可以理解为一个数组
const uint8Array = new Uint8Array(arrayBuffer); // 创建一个类型化数组对象,可以理解为上面的数组的成员,给这个对象赋值就会放到上面的数组中。
for(let i = 0; i < textData.length; i++) {
uint8Array[i] = textData.charCodeAt(i); // 将文本文件转为UTF-16的ASCII, 放到类型化数组对象中
}
return [new Blob([arrayBuffer], { type: imageType }), imageType.slice(6)]; // 返回两个值,一个Blob对象,一个图片格式(如jpeg)
}
// 转为formData
function toFormData(base64Data) {
const [imageBlob, imageType] = base64ToBlob(base64Data); // 获取处理好的Blob 和文件类型
const formData = new FormData();
formData.append('file', imageBlob, `${Date.now()}.${imageType}`); // 添加到表单,传入文件名
return formData;
}
// 上传请求
function httpRequest(formData) {
return axios({
method: 'post',
url: '', // 你的文件服务器地址
data: formData,
timeout: 60000,
headers: {
'Content-Type': 'multipart/form-data', // 请求头要设置为 form-data
'Cache-Control': 'no-cache',
},
});
}
// 上传到照片服务器
export default function upload(base64Data) {
const formData = toFormData(base64Data);
return new Promise((resolve, reject) => {
httpRequest(formData).then((res: any) => {
if (res.status === 200 && res.data.success === 1) {
resolve(res.data.path);
} else {
reject(res.data);
}
}).catch((err) => {
reject(err);
});
});
}