目的<
/h5>
- 解决富文本编辑器中复制粘贴的图片 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转url export default function base64ImgToUrl(htmlContent = ''){ return new Promise((resolve, reject) => { let splitContent = getImages(htmlContent); // 获取所有的图片 的 base64 src let res = []; for(let item of splitContent){ if(item && item.includes(';base64,')){ const file = { base64: item, }; file.file = base64toFile(item, new Date().getTime()); // 将图片转换成file res.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 = /<img[^>]+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 位无符号整型数组 初始值都是 数子0 let 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, }); }