百度UEditor粘贴内容包含大量远程图片抓取失败的问题解决
微wx笑 2021-10-26【网页网站】 3 0关键字: 百度 UEditor 远程图片抓取
在转载一些文章的时候,复制粘贴的内容可能包含大量的图片,我遇到的情况是有一二百张图片那么多,而UEditor会把所有的打包为一个请求发送给后台去抓取,这就导致一个请求需要很长时间来处理,所以经常出现请求失败的情况。
失败原因
为什么会请求失败呢?
我觉得这和服务器的CPU、内存、带宽等资源有关,当资源有限的时候,要去远程抓取一二百张图片,处理的时间就会比较长,所以导致请求失败了。
解决方法
针对这样的问题怎么解决呢?
做为程序员,肯定是去改代码了!
既然一次请求的太多了,导致失败,那么我就把请求拆分开,每次只请求10张。
思路有了,上代码!
为了修改方便,我使用的是未经过压缩的 ueditor.all.js
修改方法
找到“if (remoteImages.length) {”代码段,替换为下面的代码:
if (remoteImages.length) { console.log("remoteImages.length",remoteImages.length); console.log("开始分段抓取远程图片......"); var pk = 0; while (pk < remoteImages.length){ var imgPart = [],pkBegin = pk; for (var k = 0; k < 10; k++){ if (pk < remoteImages.length){ imgPart.push(remoteImages[pk]); pk++; } } console.log("imgPartBegin", pkBegin, "End", pk); if (imgPart.length) { console.log("imgPart", imgPart); catchremoteimage(imgPart, { //成功抓取 success: function (r) { try { var info = r.state !== undefined ? r:eval("(" + r.responseText + ")"); console.log(info); } catch (e) { console.log(e); return; } /* 获取源路径和新路径 */ var i, j, ci, cj, oldSrc, newSrc, list = info.list; for (i = 0; ci = imgs[i++];) { oldSrc = ci.getAttribute("_src") || ci.src || ""; for (j = 0; cj = list[j++];) { if (oldSrc == cj.source.replace(/&/ig, "&") && cj.state == "SUCCESS") { //抓取失败时不做替换处理 newSrc = catcherUrlPrefix + cj.url; domUtils.setAttributes(ci, { "src": newSrc, "_src": newSrc }); break; } } } me.fireEvent('catchremotesuccess') }, //回调失败,本次请求超时 error: function () { me.fireEvent("catchremoteerror"); } }); } } }
测试结果
第一次请求出现了 http cancled 错误,不知道为什么会这样,之后再测试就没有出现过了。
可喜的是,
现在拆分为多个请求,响应的就特别快了;
之前一个请求要等很久,然后返回失败,现在所有的请求都处理完也比之前用的时间短很多。
第二天测试,再次出现了 http cancled 错误,从开发者工具看似乎是并发请求的,因为在Network中看到多个抓取远程图片的请求都是处于 pending 状态,过了一会儿就变成了cancled 状态。
再次修改代码,改为一次成功之后再执行后续的请求
if (remoteImages.length) { console.log("remoteImages.length",remoteImages.length); console.log("开始分段抓取远程图片......"); var pk = 0; //while (pk < remoteImages.length){ var imgPart = [],pkBegin = pk; for (var k = 0; k < 10; k++){ if (pk < remoteImages.length){ imgPart.push(remoteImages[pk]); pk++; } } console.log("imgPartBegin", pkBegin, "End", pk); if (imgPart.length) { console.log("imgPart", imgPart); catchremoteimage(imgPart, { //成功抓取 success: function (r) { try { var info = r.state !== undefined ? r:eval("(" + r.responseText + ")"); console.log(info); } catch (e) { console.log(e); return; } /* 获取源路径和新路径 */ var i, j, ci, cj, oldSrc, newSrc, list = info.list; for (i = 0; ci = imgs[i++];) { oldSrc = ci.getAttribute("_src") || ci.src || ""; for (j = 0; cj = list[j++];) { if (oldSrc == cj.source.replace(/&/ig, "&") && cj.state == "SUCCESS") { //抓取失败时不做替换处理 newSrc = catcherUrlPrefix + cj.url; domUtils.setAttributes(ci, { "src": newSrc, "_src": newSrc }); break; } } } me.fireEvent('catchremotesuccess'); setTimeout(function(){ me.fireEvent("catchRemoteImage"); },1000); }, //回调失败,本次请求超时 error: function () { me.fireEvent("catchremoteerror"); } }); } //} }
删除了 while 循环,而是成功的回调中再次触发抓取远程图片的事件,并且设置了一秒的延迟。
2021-10-29再次测试,目前表现良好。
2022-01-23再次进行了优化,参考:在UEditor编辑器的工具栏上加一行文字或按钮
本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/web/2021-10-26/761.html