在过去的粘贴图片功能中,使用editor.config.customUploadImg可以实现单张图片上传,但是最近发现,有部分base64图片入库,因此需要另寻上传图片的方法。
单张图片上传editor.config.customUploadImg
editor.config.customUploadImg = function (resultFiles, insertImgFn) {
resultFiles.forEach((file) => {
let formdata = new FormData()
formdata.append('file', file)
attachNoticesApi(formdata).then(res => {
let imgUrl = res.data.operateCallBackObj
insertImgFn(imgUrl)
})
})
}
粘贴base64图片editor.config.pasteTextHandle
editor.config.pasteTextHandle是配置粘贴文本内容处理,是一个函数,返回值就是文本框中粘贴的数据
如果单独粘贴一张图片不会执行次函数,会直接执行图片上传函数,只有粘贴文本或者文本与图片混合时才会执行此函数。
通过这个函数可以将粘贴的图片保存到自己的服务器或其他OSS,方式原图连接失效,造成图片不显示
实现思路
先判断粘贴的信息中是否存在图片,存在就执行函数,不存在就直接返回文本。
存在图片就执行函数流程:
通过 editor.config.pasteTextHandle调用disposePasteImg处理粘贴的图片,得到图片路径,然后调用imgUrlSwitchBlob将图片路径转成图片对象,得到图片对象之后调用upPasteImg将图片进行上传并得到路径,最后以此返回。
实现粘贴文本图片替换功能,会出现一个问题,当粘贴文本,不含图片时,由于返回的是空,那么粘贴纯文本就不会执行了,在程序走到一个函数的时候就断了,无法继续执行并且还没有报错。
因此需要先判断用户粘贴的信息中是否存在图片地址,存在图片地址就执行图片上传的逻辑,不存在就直接返回。
直接在editor.config.pasteTextHandle中修改代码,在图片上传的过程中wangeditor是没有任何反应的,防止用户多次粘贴启用loading
// 配置粘贴文本的内容处理
editor.config.pasteTextHandle = function (pasteStr) {
// 需要判断是否是纯文本,不是纯文本执行函数,是纯文本返回
// 验证图片中是否包含img标签,具有得到true否则得到false
var containsImage = pasteStr.search(/<img /i) >= 0;
// 存在图片就执行
if (containsImage) {
// 打开loading
_this.pasteTextFulfill = true;
_this.disposePasteImg(pasteStr).then((res) => {
// console.log("配置粘贴文本的内容处理res", res);
editor.cmd.do('insertHTML', res) // 在光标位置插入内容
// editor.txt.append(res); // 将内容追加上
// 关闭loading
_this.pasteTextFulfill = false;
});
}
return containsImage ? "" : pasteStr;
};
最终实现纯文本直接显示,文本与图片混合会替换图片地址的功能。
在editor.config.pasteTextHandle进行调用,这时候直接返回一个空就可以了,上面的方法全部是Promise函数(在使用的函数中全部是Promise是为了解决异步的问题),得到结果的时候已经return结束了,因此不能直接返回。
使用官方提供的追加方法将数据进行追加,返回来的res就是处理好的粘贴信息。
创建函数处理粘贴的图片
函数接受的参数是editor.config.pasteTextHandle函数的参数
在这个函数中将图片地址进行提取,将图片地址传递到将图片地址转成文件对象函数中,然后通过.then获取上传之后的图片地址,将原来的图片地址进行替换,判断图片地址是否全部转换完成,转换完成之后将处理好的粘贴文本返回。
// 处理粘贴的图片,传递的参数是粘贴来的数据
disposePasteImg(pasteStr) {
let _this = this;
return new Promise(function (resolve) {
// 用于计数图片数量
let imgNum = 0;
//匹配图片
let imgReg = /<img.*?(?:>|\/>)/gi;
//匹配src属性
// eslint-disable-next-line no-useless-escape
let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;
// 提取图片连接
if(pasteStr.match(imgReg)) {
pasteStr.replace(imgReg, function (txt) {
return txt.replace(srcReg, function (src) {
let img_src = src.match(srcReg)[1];
// console.log(img_src);
//正则把?x-oss-process后面的都去掉
img_src = img_src.replace(/\?.*/i, "");
// 查找到一个图片地址就讲图片数量加1
imgNum++;
// 将图片转成图片文件对象并上传得到图片地址,传递的参数是图片地址
_this.imgUrlSwitchBlob(img_src).then((res) => {
// console.log("得到的地址res", res);
/**
* 得到图片地址进行替换并将替换之后的文本返回渲染
*/
// 图片地址进行替换
pasteStr = pasteStr.replace(img_src, res);
// 替换之后将图片数量减1
imgNum--;
// 只有图片数量变成0的时候才会进行返回
if (imgNum == 0) {
// console.log("返回imgNum", imgNum,pasteStr)
resolve(pasteStr);
}
});
});
});
}else{
resolve(pasteStr);
}
});
},
将图片地址转成文件对象
在函数disposePasteImg函数中调用了本函数,参数是图片地址本函数是通过创建图片对象将图片地址转成图片对象(图片文本),在本函数中需要提前确定文件的名称,图片上传函数不会在接受图片地址,只会接受文件名称和文件对象
/**
* @函数名称: 将图片地址转成文件对象
* @返回值:图片地址
* @描述: 接受的参数是图片的全地址路径,在函数中调用upPasteImg函数上传图片得到图片路径并返回
* @其它: 使用Promise处理异步问题
* @param {String} param 图片地址
*/
imgUrlSwitchBlob(param) {
let _this = this;
return new Promise(function (resolve) {
// 得到图片后缀
let suffix = param.substring(param.lastIndexOf(".") + 1); //获取后缀
// 设置图片名称及后缀
const key =
new Date().getTime() +
Math.random().toString().substr(2, 5) +
"." +
suffix;
// 创建图片对象
let image = new Image();
// 允许跨域
image.setAttribute("crossOrigin", "anonymous");
image.src = param;
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob((blob) => {
// console.log("blob", blob)
// 得到的blob是一个图片对象,经图片对象进行上传得到图片地址.key是文件名称
/**
* @函数名称: 调用函数进行上传
* @返回值: 得到的图片路径
* @param {String} key 图片名称,包含后缀
* @param {Object} blob 文件对象
*/
_this.upPasteImg(key, blob).then((res) => {
resolve(res);
});
});
};
});
},
图片上传服务器
得到对象和文件名称之后就可以直接上传到服务器或者其他OSS
上传文件需要调用后端接口获取token,获取到token之后配置信息实现上传。
最后将得到的图片地址依次返回
/**
* @函数名称: 上传粘贴的图片
* @返回值: 上传得到的图片地址
* @其它: 使用Promise处理异步问题
* @param {String} key 文件名称
* @param {Object} file 文件对象
*/
upPasteImg(key, file) {
let _this = this;
let formdata = new FormData()
formdata.append('file', file)
return new Promise(function (resolve) {
attachNoticesApi(formdata).then(res => {
let imgUrl = res.data.operateCallBackObj
resolve(imgUrl)
})
})
},