目的
  • 解决富文本编辑器中复制粘贴的图片 base64 字符串过长导致无法存储到数据库的问题
思路
  • 通过正则 获取html字符串中里面的所有图片 base64 数组 然后每个图片base64 转成file
  • 使用上传文件的函数 上传到服务器上.
  • 将上传后获取到的图片访问url 替换成 数据里面的 img 的 src.
代码
/** * 将html中的 图片base64 通过调上传文件接口转换成图片url * *//**上传文件**/export function uploadFile(params) {let url = `/upload`; // const formData = new FormData();for (let item in params) {formData.append(item, params[item]);}return fetch(url, {method: 'POST',headers: {Accept: '*/*',},body: formData,}).then((res) => {return res.json();}).then((responseData) => {if(responseData && typeof responseData === 'object' && responseData.url){return responseData;}if (responseData && responseData.data) {return responseData.data;} else {throw new Error('文件上传失败');}}).catch(() => {throw new Error('上传文件失败');});}// base64转urlexport default function base64ImgToUrl(htmlContent = ''){return new Promise((resolve, reject) => {let splitContent = getImages(htmlContent);// 获取所有的图片 的 base64 srclet res = [];for(let item of splitContent){if(item && item.includes(';base64,')){const file = {base64: item,};file.file = base64toFile(item, new Date().getTime()); // 将图片转换成fileres.push(file);}} // 任务列表async function DoTaskByForOf() {for (let item of res) { // 按顺序执行const fileResponse = await uploadFile({file:item.file}); // 上传文件到服务器if(fileResponse && fileResponse.url){item.url = fileResponse.url;}}return res;}DoTaskByForOf().then((r) => {resolve(r);}); // 按顺序执行})}/** * 使用正则表达式从HTML字符串中获取所有图像src * */export function getImages(html) {const regExp = /]+src=['"]([^'"]+)['"]+/g;const result = [];let temp;while ((temp = regExp.exec(html)) != null) {result.push(temp[1]);}return result;}/** * 把base64图片转为文件对象 * 第一个参数dataUrl是一个base64的字符串。第二个参数是文件名可以随意命名 */export function base64toFile(dataUrl = '', filename = 'file') {let arr = dataUrl.split(',');let mime = arr[0].match(/:(.*?);/)[1];// suffix是该文件的后缀let suffix = mime.split('/')[1];// atob 对经过 base-64 编码的字符串进行解码let bstr = atob(arr[1]);// n 是解码后的长度let n = bstr.length;// Uint8Array 数组类型表示一个 8 位无符号整型数组 初始值都是 数子0let u8arr = new Uint8Array(n);// charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数while (n--) {u8arr[n] = bstr.charCodeAt(n);}// new File返回File对象 第一个参数是 ArraryBuffer 或 Bolb 或Arrary 第二个参数是文件名// 第三个参数是 要放到文件中的内容的 MIME 类型return new File([u8arr], `${filename}.${suffix}`, {type: mime,});}