网页网站您现在的位置是:首页 > 博客日志 > 网页网站

百度UEditor粘贴内容包含大量远程图片抓取失败的问题解决

<a href='mailto:'>微wx笑</a>的头像微wx笑 2021-10-26网页网站 3 0关键字: 百度  UEditor  远程图片抓取  

在转载一些文章的时候,复制粘贴的内容可能包含大量的图片,我遇到的情况是有一二百张图片那么多,而UEditor会把所有的打包为一个请求发送给后台去抓取,这就导致一个请求需要很长时间来处理,所以经常出现请求失败的情况。

失败原因

为什么会请求失败呢?T5Y无知

我觉得这和服务器的CPU、内存、带宽等资源有关,当资源有限的时候,要去远程抓取一二百张图片,处理的时间就会比较长,所以导致请求失败了。
T5Y无知

解决方法

针对这样的问题怎么解决呢?T5Y无知

做为程序员,肯定是去改代码了!T5Y无知

既然一次请求的太多了,导致失败,那么我就把请求拆分开,每次只请求10张。T5Y无知

思路有了,上代码!T5Y无知

为了修改方便,我使用的是未经过压缩的 ueditor.all.jsT5Y无知


T5Y无知

修改方法

找到“if (remoteImages.length) {”代码段,替换为下面的代码:T5Y无知

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(/&amp;/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 错误,不知道为什么会这样,之后再测试就没有出现过了。T5Y无知

可喜的是,T5Y无知

现在拆分为多个请求,响应的就特别快了;T5Y无知

之前一个请求要等很久,然后返回失败,现在所有的请求都处理完也比之前用的时间短很多。T5Y无知


T5Y无知

第二天测试,再次出现了 http cancled 错误,从开发者工具看似乎是并发请求的,因为在Network中看到多个抓取远程图片的请求都是处于 pending 状态,过了一会儿就变成了cancled 状态。 T5Y无知

再次修改代码,改为一次成功之后再执行后续的请求T5Y无知

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(/&amp;/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 循环,而是成功的回调中再次触发抓取远程图片的事件,并且设置了一秒的延迟。T5Y无知


T5Y无知

2021-10-29再次测试,目前表现良好。T5Y无知


T5Y无知

2022-01-23再次进行了优化,参考:在UEditor编辑器的工具栏上加一行文字或按钮T5Y无知


T5Y无知

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/web/2021-10-26/761.html

很赞哦! () 有话说 ()