ueditor解决无法抓取远程背景图片问题的方法(php)

背景

laravel后台经常有用到编辑器的地方,Dcat使用的一般都是UEditor编辑器。最近项目经理在秀米排版以后,将内容复制到UEditor编辑器保存后发现,

在网站页面中发现图片竟然展示失败。经过浏览器控制台发现,图片的域名还是秀米的,那就好说了

解决方案

一、修改配置,允许抓取远程图片

  • UEditor很强大,直接就有配置,开启还是关闭抓取外部图片到本地服务器,该配置在ueditor.config.js文件中,搜索catchRemoteImageEnable,如下图:

但是发现项目配置中已经开启了该功能,但是图片还是不展示,那就继续看页面元素,后来发现未抓取过来的图片是背景图。。。。真相了哈,那就修改抓取的代码,增加一个抓取背景图的逻辑

二、增加抓取背景图中的远程图片

1、打开文件ueditor.all.js文件,找到catchRemoteImage方法

2、直接修改该方法

javascript 复制代码
/**
 * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片
 */
UE.plugins['catchremoteimage'] = function () {
    var me = this,
        ajax = UE.ajax;

    /* 设置默认值 */
    if (me.options.catchRemoteImageEnable === false) return;
    me.setOpt({
        catchRemoteImageEnable: false
    });

    me.addListener("afterpaste", function () {
        me.fireEvent("catchRemoteImage");
    });

    me.addListener("catchRemoteImage", function () {
        console.log("开始抓取" );

        var catcherLocalDomain = me.getOpt('catcherLocalDomain'),
            catcherActionUrl = me.getActionUrl(me.getOpt('catcherActionName')),
            catcherUrlPrefix = me.getOpt('catcherUrlPrefix'),
            catcherFieldName = me.getOpt('catcherFieldName');

        var remoteImages = [],
            imgs = domUtils.getElementsByTagName(me.document, "img"),
            backgroundimagestags = domUtils.getElementsByTagName(me.document, "section span div p "),//抓取背景图片所在的标签
            test = function (src, urls) {
                if (src.indexOf(location.host) != -1 || /(^\.)|(^\/)/.test(src)) {
                    return true;
                }
                if (urls) {
                    for (var j = 0, url; url = urls[j++];) {
                        if (src.indexOf(url) !== -1) {
                            return true;
                        }
                    }
                }
                return false;
            };

        //img标签
        for (var i = 0, ci; ci = imgs[i++];) {
            if (ci.getAttribute("word_img")) {
                continue;
            }
            var src = ci.getAttribute("_src") || ci.src || "";
            if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) {
                remoteImages.push(src);
            }
        }

        //背景图片所在标签
        var backgroundimages = [];
        // console.log("背景图片个数:" + backgroundimagestags.length);
        for (var i = 0, backci; backci = backgroundimagestags[i++];) {

            var bstyle = backci.style;
            var backgroundimgurltag = bstyle['background-image'] || bstyle['background'] || "";
            if (backgroundimgurltag != null && backgroundimgurltag != "") {
                var backsrc = backgroundimgurltag.split("(")[1].split(")")[0].replace(/\"/g, "")
                    || backgroundimgurltag.split("(")[1].split(")")[0].replace(/\"/g, "")
                    || "";
                // console.log("ci_src:" + backsrc);
                if (backsrc != null && backsrc != "") {
                    if (/^(https?|ftp):/i.test(backsrc) && !test(backsrc, catcherLocalDomain)) {
                        backgroundimages.push(backsrc);
                        remoteImages.push(backsrc);
                    }
                }
            }
            // console.log("remoteImages个数:" + remoteImages.length);
        }

        if (remoteImages.length) {
            me.fireEvent('catchremotestart');
            catchremoteimage(remoteImages, {
                //成功抓取
                success: function (r) {
                    try {
                        var info = r.state !== undefined ? r:eval("(" + r.responseText + ")");
                    } catch (e) {
                        return;
                    }

                    /* 获取源路径和新路径 */
                    var i, j, ci, cj, oldSrc, newSrc, list = info.list;


                    //img标签的替换
                    for (i = 0; ci = imgs[i++];) {
                        oldSrc = ci.getAttribute("_src") || ci.src || "";
                        for (j = 0; cj = list[j++];) {
                            if (oldSrc == cj.source && cj.state == "SUCCESS") {  //抓取失败时不做替换处理
                                newSrc = catcherUrlPrefix + cj.url;
                                domUtils.setAttributes(ci, {
                                    "src": newSrc,
                                    "_src": newSrc
                                });
                                break;
                            }
                        }
                    }

                    //背景图片地址的替换
                    var bodyHtml = me.document.body.innerHTML;
                    console.log("上传之前html:" + bodyHtml);
                    for (var a = 0; a < backgroundimages.length; a++) {
                        oldSrc = backgroundimages[a] || "";
                        for (j = 0; cj = list[j++];) {
                            if (oldSrc == cj.source && cj.state == "SUCCESS") {  //抓取失败时不做替换处理
                                newSrc = catcherUrlPrefix + cj.url;
                                console.log("上传之后oldSrc:" + oldSrc);
                                console.log("上传之后newSrc:" + newSrc);
                                // console.log("上传之后html:" + me.document.body.innerHTML.replace(oldSrc, newSrc));

                                //判断旧地址中,是不是有双引号,有的话,替换成单引号
                                if(bodyHtml.indexOf('&quot;'+oldSrc +'&quot;') ){
                                    console.log(45674567890);
                                    bodyHtml = bodyHtml.replace('&quot;'+oldSrc +'&quot;', '&#39;'+newSrc +'&#39;');
                                }else{
                                    console.log("不用替换");
                                    bodyHtml = bodyHtml.replace(oldSrc, newSrc);
                                }

                                console.log("替换之后html:" + bodyHtml);
                                break;
                            }
                        }
                    }
                    me.document.body.innerHTML = bodyHtml;

                    me.fireEvent('catchremotesuccess');
                    me.fireEvent('catchremotecomplete');
                },
                //回调失败,本次请求超时
                error: function () {
                    me.fireEvent("catchremoteerror");
                }
            });
        }

        function catchremoteimage(imgs, callbacks) {
            console.log("1111L:" + imgs.length);
            var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '',
                url = utils.formatUrl(catcherActionUrl + (catcherActionUrl.indexOf('?') == -1 ? '?':'&') + params),
                isJsonp = utils.isCrossDomainUrl(url),
                opt = {
                    'method': 'POST',
                    'dataType': isJsonp ? 'jsonp':'',
                    'timeout': 60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值
                    'onsuccess': callbacks["success"],
                    'onerror': callbacks["error"]
                };
            opt[catcherFieldName] = imgs;
            ajax.request(url, opt);
        }

    });
};
  • 3、里面修改双引号为单引号的部分,是我发现图片是抓取过来了,但是ueditor编辑器回显的时候,因为双引号导致展示不出来,而额外加的。即使不加,网站前台展示也是正常的哟
相关推荐
BingoGo12 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack12 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理3 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082853 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe3 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5
longxiangam3 天前
Composer 私有仓库搭建
php·composer
上海云盾-高防顾问3 天前
DNS异常怎么办?快速排查+解决指南
开发语言·php