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

背景

laravel后台经常有用到编辑器的地方,Dcat使用的一般都是UEditor编辑器。最近项目经理在秀米排版以后,将内容复制到UEditor编辑器保存后发现,
在网站页面中发现图片竟然展示失败。经过浏览器控制台发现,图片的域名还是秀米的,那就好说了

解决方案

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

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

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

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

1、打开文件ueditor.all.js文件,找到catchRemoteImage方法
2、直接修改该方法

/*** 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片*/
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编辑器回显的时候,因为双引号导致展示不出来,而额外加的。即使不加,网站前台展示也是正常的哟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/362751.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Arathi Basin (AB) PVP15

Arathi Basin &#xff08;AB&#xff09; PVP15 阿拉希盆地&#xff0c;PVP&#xff0c;15人战场

【手撕代码】握手机制

文章目录 为什么要握手握手信号无非3种可能 怎样实现握手案例一&#xff1a;数据反压 参考链接 为什么要握手 跨时钟域处理&#xff1a; 握手信号法其实也用到了脉冲展宽的方法&#xff0c;只是展宽信号的变化条件不同。因为如果不对脉冲进行展宽&#xff0c;慢速时钟域的时钟…

生产者发送数据,kafka服务器接收数据异常的问题记录

现象&#xff1a; 某个客户要求审计日志用kafka的方式传输给他们&#xff0c;使用了第三方的librdkafka库来开发。 往客户提供的kafka服务器上的一个topic发送数据&#xff0c;这个topic有三个分区&#xff0c;客户反馈接收到的数据和发送端发送的实际数量对不上&#xff0c;他…

一款开源、免费、现代化风格的WPF UI控件库

前言 今天大姚给大家分享一款开源&#xff08;MIT License&#xff09;、免费、现代化风格的WPF UI控件库&#xff1a;ModernWpf。 项目介绍 ModernWpf是一个开源项目&#xff0c;它为 WPF 提供了一组现代化的控件和主题&#xff0c;使开发人员能够创建具有现代外观的桌面应…

Java——IDEA使用

一、IDEA介绍 IntelliJ IDEA 是 JetBrains 公司开发的一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于 Java 编程语言&#xff0c;但也支持多种其他语言和框架。由于其强大的功能和灵活性&#xff0c;IntelliJ IDEA 被广泛应用于软件开发领域&…

2、Redis持久化与高可用架构

一、Redis 持久化 RDB 快照&#xff08;Snapshot&#xff09; 基本概念&#xff1a;RDB&#xff08;Redis DataBase&#xff09;快照是将 Redis 内存中的数据在某个时间点保存到磁盘中的一种持久化方式&#xff0c;默认保存到 dump.rdb 的二进制文件中。通过 RDB 快照&#xff…

hnust 1817 算法10-10,10-11:堆排序

hnust 1817 算法10-10,10-11&#xff1a;堆排序 题目描述 堆排序是一种利用堆结构进行排序的方法&#xff0c;它只需要一个记录大小的辅助空间&#xff0c;每个待排序的记录仅需要占用一个存储空间。 首先建立小根堆或大根堆&#xff0c;然后通过利用堆的性质即堆顶的元素是最…

基于单片机和组态王的温度监控系统的设计

摘 要 : 介绍了以 MSP430 单片机为核心 , 建立基于 DS18B20 和组态王的温度采集和监控系统。主要研究了单片机和组态王的通用通讯协议。按照 KingView 提供的通信协议 , 设计组态王与单片机的通信程序 , 实现了组态王与M SP430 单片机的直接串行通讯。在中药提取装置的…

huggingface加速下载模型

文章目录 所需环境huggingface-cli 用法登录token 获取 huggingface 镜像huggingface 缓存hf-transfer 拉满下载带宽如果开了的话&#xff0c;记得关掉科学上网&#xff01;&#xff01;&#xff01; 所需环境 python huggingface-cli 用法 huggingface-cli的更多用法点击这…

用一个实例看如何分享大量照片 续篇二,关于Exif (Exchangeable Image File) - 可交换图像文件

续篇二&#xff1a;说说关于照片隐含的 Exif (Exchangeable Image File) 可交换图像文件 数码照片的Exif 参数有很多&#xff0c;重要的Exif信息&#xff1a;拍摄日期、时间、拍摄器材、GPS信息。 当然这主要对自己的档案有意义&#xff0c;如果放到网上还是建议抹去这些信息。…

【数据结构与算法】堆 详解

什么是堆&#xff1f; 堆是一种特殊的完全二叉树&#xff0c;它满足堆的性质&#xff1a;在最大堆中&#xff0c;对于除了根之外的每个节点i&#xff0c;都有A[parent(i)] > A[i]&#xff1b;在最小堆中&#xff0c;对于除了根之外的每个节点i&#xff0c;都有A[parent(i)]…

数据挖掘常见算法(关联)

Apriori算法 Apriori算法基于频繁项集性质的先验知识&#xff0c;使用由下至上逐层搜索的迭代方法&#xff0c;即从频繁1项集开始&#xff0c;采用频繁k项集搜索频繁k1项集&#xff0c;直到不能找到包含更多项的频繁项集为止。 Apriori算法由以下步骤组成&#xff0c;其中的核…

AI进阶指南第五课,大模型相关概念(知识库,微调)

虽然前面大概讲了一下大模型的一些基本概念&#xff0c;但是那些都比较偏向于大模型本身&#xff0c;但是我们使用的时候如果只靠大模型肯定是不行的。 就好比如果一个人只有一个脑子&#xff0c;其他什么部位也没有的话&#xff0c;那场面。&#xff08;感觉现在网上的AI图片…

新能源汽车CAN总线故障定位与干扰排除的几个方法

CAN总线是目前最受欢迎的现场总线之一,在新能源车中有广泛应用。新能源车的CAN总线故障和隐患将影响驾驶体验甚至行车安全,如何进行CAN总线故障定位及干扰排除呢? 目前,国内机动车保有量已经突破三亿大关。由于大量的燃油车带来严峻的环境问题,因此全面禁售燃油车的日程在…

下拉选择输入框(基于elment-ui)

最近在需求中&#xff0c;需要有一个下拉选择功能&#xff0c;又得可以输入&#xff0c;在 element-ui 官网找了&#xff0c;发现没有适合的&#xff0c;然后在修炼 cv 大法的我&#xff0c;也在网上看了一下&#xff0c;但是也都感觉不合适&#xff0c;所以就自己写了两个&…

Android开发系列(十二)Jetpack Compose之BottomSheet

BottomSheet 是 Android 中一个常用的 UI 组件&#xff0c;它通常用于显示从屏幕底部弹出的用户界面。Jetpack Compose 是 Android 中的一个全新 UI 工具包&#xff0c;它提供了一种声明式的方式来构建用户界面。Jetpack Compose 中也有一个名为 BottomSheet 的组件&#xff0c…

生命在于学习——Python人工智能原理(2.5.1)

五、Python的类与继承 5.1 Python面向对象编程 在现实世界中存在各种不同形态的事物&#xff0c;这些事物之间存在各种各样的联系。在程序中使用对象来映射现实中的事物&#xff0c;使用对象之间的关系描述事物之间的联系&#xff0c;这种思想用在编程中就是面向对象编程。 …

03逻辑门电路

分立门电路&#xff1a; 集成门电路&#xff1a; TTL门电路 MOS门电路&#xff1a;NMOS门电路、PMOS门电路、CMOS门电路 BICMOS门电路&#xff1a;CMOS的高输入阻抗和TTL的高放大倍数的结合 向更低功耗、更高速度发展 MOS管的Rdson在可变电阻区的阻值也一般会小于1000欧姆 …

数字时代的文化革命:Facebook的社会影响

随着数字技术的飞速发展和互联网的普及&#xff0c;社交网络如今已成为人们日常生活中不可或缺的一部分。在众多社交平台中&#xff0c;Facebook作为最大的社交网络之一&#xff0c;不仅连接了全球数十亿用户&#xff0c;更深刻影响了人们的社会互动方式、文化认同和信息传播模…

Golang | Leetcode Golang题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; func isHappy(n int) bool {cycle : map[int]bool{4: true, 6: true, 37: true, 58: true, 89: true, 145: true, 42: true, 20: true}for n ! 1 && !cycle[n] {n step(n)}return n 1 }func step(n int) int {sum : 0for n > …