zxdsb666. 发表于 2020-10-11 14:23

百度编辑器的那些坑

本帖最后由 zxdsb666. 于 2020-10-11 14:25 编辑

# 百度编辑器的那些坑:

## 前言:

最近在处理公司的旧后台浏览器兼容问题,要求更换`ewebeditor` 编辑器,更换为ueditor 编辑器,并且要求 IE9/IE8/IE10/IE11/Micro Edge/Google/360 编辑器各项兼容,听说百度的编辑器兼容至IE6,以为简单的换个编辑器的我,在上面折腾了不少时间,本文针对具体问题进行处理,可能读者遇不到我这样的问题,事前说明:**仅供参考**、**仅供参考**、**仅供参考**

<!-- more -->

## 问题:

1. 百度编辑器粘贴图片的时候,会出现暴露内网IP的隐患- IE问题
2. 百度编辑器`Ctril + v`粘贴图片功能在IE上面不触发任何效果的问题
3. 特殊符号传输后台的转义问题,以及将数据库的html读取之后,由于双引号导致的截取页面报错问题
4. 针对 `iframe`这种嵌套框架,在保存的之后,拿不到编辑器内容的兼容处理方式

## 百度编辑器粘贴图片的时候,会出现暴露内网IP的隐患- IE问题

### 问题复现

使用粘贴图片就会出现如下的问题,在查看源代码的时候,出现了如图所示的暴露源代码的问题,出现问题原因不明:

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011120300.png)

### 解决办法:

1. 非常简单,只需要关闭`查看源代码`的按钮就行,完美解决
2. 如果一定要保留,在不知道如何处理的情况下,并且急需交差的时候,可以这么干(当时情况是第二天就得交差,由于一直找不到问题点,加班到晚上10想出来的办法)

### 障眼法:

先直接上代码:

```javascript
// 点击源代码按钮对于编辑器的内容进行敏感href信息处理 2019.9.24
    $('body').delegate(".edui-button-wrap","click",function(){
      var editTxt = $('.edui-editor-iframeholder').find('textarea')
      if(editTxt.length){
            var content = UE.getEditor('ueditor').getContent();
            var aE = $('<div></div>');
            aE.html(content)
            // alert(aE)
            aE.find('p.filedata').each(function(){
                var newA = $(this).find('a')
                // alert(newA.attr('href'))
                if(newA.attr('href').indexOf("http://")>=0 || newA.attr('href').indexOf("https://")>=0){
                  var arr = newA.attr('href').split('/')
                  var newTxt = ''
                  for(var i=3; i<arr.length;i++){
                        newTxt +='/'+arr
                  }
                  newA.attr('href',newTxt)
                }

            })
            // alert(content);
            // 获取转义之后的字符
            var formatTxt = toTxt(aE.html());
            // formatTxt = appendBrToPAlfter(formatTxt);
            editTxt.html(formatTxt);

      }
    });

    /*正则表达式 替换括号,尖括号等*/
    function toTxt(str) {
      var RexStr = /\<|\>|\"|\'|\&/g
      str = str.replace(RexStr, function(MatchStr) {
            switch (MatchStr) {
                case "<":
                  return "&lt;";
                  break;
                case ">":
                  return "&gt;";
                  break;
                case "\"":
                  return "&quot;";
                  break;
                case "'":
                  return "&#39;";
                  break;
                case "&":
                  return "&amp;";
                  break;
                default:
                  break;
            }
      })
      return str;
    }

```

1. 绑定一个失去焦点的事件,在读取源代码的时候,对于内容进行截断
2. 重新为href 赋值,保证连接无内网地址
3. 去除掉内容里面的特殊标签,
4. 重新为富文本框赋值



### 总结:

1. 比较搞笑的解决方式,但是当领导掐着你脖子的时候,解决问题永远是第一位。至少这种方式上线之后,没有反馈出现过问题,各个版本的浏览器都是兼容的,算是逃过一劫
2. 个人建议富文本编辑器有空多去玩玩查看源代码的功能,有时候编辑器的默认设置可能会坑了你,比如百度编辑器默认会加上 p 标签。。。。



## 特殊符号传输后台的转义问题,以及读取数据的问题

## &

## 针对 `iframe`这种嵌套框架,在保存的之后,拿不到编辑器内容的兼容处理方式

### 问题复现:

​        由于旧后台是使用iframe进行拼接旧后台系统,在保存的时候,表单无法拿到富文本编辑框的内容,并且在读取的时候,会导致一些样式代码被截断导致内容显示不全的问题。

​        我们都知道富文本在数据库存储的一般都是html原文,一般的系统都会对一些 < > \ $ % 这种字符进行转义处理或者拦截。所以我们直接用js传原生文本肯定是不行的,需要进过如下的处理:

存储的时候:

1. 转移特殊符号,替换原文本
2. 拦截器拦截检测是否有特殊文本,进行二次转义
3. 存储之前,将转义字符变为原始 < > 等标签,替换内容
4. 将富文本存储到数据库,完成

读取的时候:

1. 读取数据库的内容
2. 回显内容到富文本编辑器(这一步其实会遇到非常多的奇怪问题,请看下文)

​        至于保存的时候,这里的实际情况是,旧版本的ewebeditor,在父iframe也就是表单的父页面使用了一个`textarea` 标签来保存具体的内容,导致即使我在`iframe`操作之后,依然会出现问题。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011124205.png)



### 解决办法:

也是直接上代码:

```javascript
var ue = UE.getEditor('ueditor');

    //初始化内容
    window.onload = function(){
      setTimeout(function(){
            ue.setContent($('#'+QueryStringByName('id'), parent.document).val())
      },500)
    }

    // 绑定失去焦点事件
    ue.addListener('blur',function(editor){
      var content = UE.getEditor('ueditor').getContent();
      var aE = $('<div></div>');

      aE.html(content)
      aE.find('p.filedata').each(function(){
            var newA = $(this).find('a')
            if(newA.attr('href').indexOf("http://")>=0 || newA.attr('href').indexOf("https://")>=0){
                var arr = newA.attr('href').split('/')
                var newTxt = ''
                for(var i=3; i<arr.length;i++){
                  newTxt +='/'+arr
                }
                newA.attr('href',newTxt)
            }

      })
      content = toTxt(aE.html());
      //alert(content);
      $('#'+QueryStringByName('id'), parent.document).html(content)
    });

    //获取search参数
    function QueryStringByName(name){
      var result=window.location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
      if(result==null || result.length<0){
            return "";
      }
      return result;
    }
```

1. 在初始化的时候,跑去父窗口拿到数据的文本内容,做了一点点的延时加载。
2. 使用`blur` 事件做 `textarea` 和 富文本编辑器的双向同步
3. 同样需要处理内网地址暴露的问题,需要截取内网地址
4. 对于特殊标签转义



### 总结:

1. 富文本暂存区域,最好选隐藏域的 `textarea`,使用value 值会出现双引号截取的问题
2. 小心转义带来的各种问题,一定要记得何时数据会被转义,同时什么阶段的数据内容是什么形式
3. 关注富文本编辑器本身干的一些"`杂活`"



## 处理百度编辑器粘贴在IE失效的问题(目前未找到解决方案)

### 问题复现:

这也是我要说的重点问题,目前我依然没有找到解决办法,下面的内容都是我的个人尝试,希望找到有过处理经验的人或者有其他方式的办法,有偿感谢!!

第一个问题:在IE当中,使用`ctrl + V ` 是没有任何反应和效果的,而在谷歌的浏览器下面,

第二个问题:在IE中, 复制粘贴word内容无法粘贴图片



### 无法解决的办法:

https://www.cnblogs.com/songsu/p/11915470.html

遇事不决找谷歌,谷歌出了一篇这种文章,试下

大概在`ueditor.all.js`文件的23881行左右

```javascript
bindEvents:{
            //插入粘贴板的图片,拖放插入图片
            'ready':function(e){
                var me = this;
                if(window.FormData && window.FileReader) {
                  domUtils.on(me.body, 'paste drop', function(e){
                        //判断剪贴板的内容是否包含文本
                        //首先解释一下为什么要判断文本是不是为空
                        //在ctrl+c word中的文字或者图片之后会返回1种(image/png)或者4种type(text/plain,text/html,text/rtf,image/png)类型的对象
                        //为了兼容4种格式的情况,做了如下的判断
                        //如下代码:e.originalEvent.clipboardData.items获得剪贴板的内容
                        //当粘贴了文本之后text是不为空的,同时也会返回当前文本的图片类型
                        //如果有文字的话不做任何的处理,如果只粘贴图片的话文本一定是空的,包括复制的桌面图片或者截图的图片
                        // var text = e.originalEvent.clipboardData.getData("text");
                        // if(text == ""){
                        //   var items=e.originalEvent.clipboardData.items;
                        //   for (var i = 0, len = items.length; i < len; i++) {
                        //         var item = items;
                        //         if ( item.kind == 'file' && item.type.indexOf('image/') !== -1 ) {
                        //             var blob = item.getAsFile();
                        //             getBase64(blob, function( base64 ) {
                        //               //sendAndInsertImage(base64,me); 上传到服务器
                        //               setBase64Image(base64,me);
                        //             });
                        //             //阻止默认事件, 避免重复添加;
                        //             e.originalEvent.preventDefault();
                        //         };
                        //   }
                        // }

                        //TODO 粘贴图片的根本问题点 20201010
                        var hasImg = false,
                            items;
                        //获取粘贴板文件列表或者拖放文件列表
                        items = e.type == 'paste' ? getPasteImage(e):getDropImage(e);
                        if(items){
                            var len = items.length,
                              file;
                            while (len--){
                              file = items;
                              if(file.getAsFile) file = file.getAsFile();
                              if(file && file.size > 0) {
                                    sendAndInsertFile(file, me);
                                    hasImg = true;
                              }
                            }
                            hasImg && e.preventDefault();
                        }

                  });
                  //取消拖放图片时出现的文字光标位置提示
                  domUtils.on(me.body, 'dragover', function (e) {
                        if(e.dataTransfer.types == 'Files') {
                            e.preventDefault();
                        }
                  });

                  //设置loading的样式
                  utils.cssRule('loading',
                        '.loadingclass{display:inline-block;cursor:default;background: url(\''
                            + this.options.themePath
                            + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n' +
                            '.loaderrorclass{display:inline-block;cursor:default;background: url(\''
                            + this.options.themePath
                            + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' +
                            '}',
                        this.document);
                }
            }
      }
```

针对内容进行的处理操作

```javascript
function getPasteImage(e){
   
      return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items.type) ? e.clipboardData.items:null;
    }
    function getDropImage(e){
      returne.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files:null;
    }


    //TODO 执行插入图片的操作 20201010
    function setBase64Image(base64, editor) {
      editor.execCommand('insertimage', {
            src: base64,
            _src: base64
      });
    }

    //TODO 获得base64 20201010
    function getBase64(blob, callback) {
      var a = new FileReader();
      a.onload = function(e) {
            callback(e.target.result);
      };
      a.readAsDataURL(blob);
    };

```

博客的方式是读取二进制流为Blob,然后调用原始的上传接口进行兼容,然而,我在直接套用之后,连谷歌的粘贴也失效了**(坑爹!)**

不用怀疑,肯定是:`getPasteImage()`中没有拿到想要的结果,所以我直接`alert`打印想要的内容,看下什么内容

加入代码`console.log(e.clipboardData)`看下IE什么效果(注意要使用高版本IE)

>记得在测试之前,在粘贴板粘贴带图片内容的word内容,或者截个图粘贴到IE的富文本编辑框

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011132122.png)

不出所料,没有内容,我们直接打印 e 事件对象,看看有没有想要的内容

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011132536.png)

错了,使用console:

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011133204.png)

说实话,看不懂,凭感觉这里的`dataTransfer`没有内容,基本上是找不到如何获取粘贴板数据的点

所以个人判断是IE浏览器本身就对这种粘贴操作没有进行兼容或者处理(万恶的IE浏览器)

至此,我知道自己的能力不足,无法解决这个问题,所以跑去问前端了,然后前端百度一圈下来,和我说:"要不换个编辑器?"

我没有死心,继续搜索

### 其他方式:

其实有其他的组织或者公司已经对于这种word的上传问题进行了解决

(https://blog.csdn.net/myfmyfmyfmyf/article/details/18399329)

总结:

1. 思路不错,但是基本属于闭门造车,并且还要安装一个exe的Active控件,无法解决问题
2. 自己重写一个Active控件兼容处理

[富文本编辑器粘贴word内容](http://blog.ncmem.com/wordpress/2019/08/07/%E5%AF%8C%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E7%B2%98%E8%B4%B4word%E5%86%85%E5%AE%B9/)

总结:

1. 其他公司二次开发,商用版本
2. 个人版本要300多一年,比较麻烦
3. 也是基于word的上传开发了插件,并且需要安装word上传的控件
4. 感兴趣可以下载看下,localhost 和 "127.0.0.1" 可以正常上传和使用

(https://www.cnblogs.com/yangzhi/p/3576527.html)

总结:

1. 不是一码事,针对上传操作做了一些兼容和优化而已,无法解决粘贴的问题

官方Github:
问题描述:从word中复制的图片粘贴到UEditor中以后不能正常显示,work图片转存的按钮也不可用。

解决方案:参看 (https://github.com/fex-team/ueditor/issues/2883)

总结:

1. 虽然官方的ISSUE 有人提过了,但是我访问404 啊。。。。
2. 现在已经邮箱打扰,不知道给不给我这个菜鸟回复。。。。

经过上面的尝试之后,发现还是没有特别好的解决方式,于是反馈给上级,不让问题留在自己手里。。。。。

连官方那边都找不到办法,有点万念俱灰,于是把问题往上抛了,八成需要换编辑器,又有的忙了。。。。

## 分享:

说了这么多,其实我最想说的是,解决问题建议各位一定要留下文档记录,哪怕是如何解决的也好。

我是一个后端的开发人员,但是却被安排到前端去处理前端的兼容性问题,其实当时顶着非常大的压力的,客户催得紧,经理也天天问我进度,辛好公司有一位干过全栈的大神在,我的许多奇葩的样式错乱和按钮点击问题都是找他帮忙解决的,我对IE的各种奇怪现象其实挺恶心的,最后还是拖累同事陪我加班到十点解决上面的暴露内网的问题。在解决之后,我说了这么一句话:“我这辈子都不想碰到IE了”,但是那位全栈的同事却和我说:“怕什么,我连IE6的兼容性都搞过,不是照样搞好,这些问题解决之后,这就是属于你的经验,你不断积累经验,才能比别人更多优势”,这对我今年的工作态度产生了很多的工作影响,我不在思考为了工作而工作,而是思考为了自己而工作,希望我的话对大家有帮助。

![](https://gitee.com/lazyTimes/imageReposity/raw/master/img/20201011125214.png)

# 最后总结:

就以我这个老掉牙的系统来说,目前百度的编辑器兼容和支持是最好的,实在不想再换别的浏览器,或者说换之前再挣扎一下,所以写下。

欢迎各位前端大神指教,帮助一下我这个后端临时抽来解决前端问题的人QAQ

如果有好的解决方式,欢迎拍砖

zxdsb666. 发表于 2020-10-11 15:50

www.52pojie.cn 发表于 2020-10-11 15:35
百度的产品都是带漏洞的车,一边走一边漏,用户自己还得下车捡

心累,这编辑器说好也不咋地,说坏又觉得挺好

zxdsb666. 发表于 2020-10-11 18:50

moganok 发表于 2020-10-11 18:35
这些问题我几年前就解决过,基本上源代码修补。。。。。

其实已经有这个想法了,只是还想挣扎一下

魔幻冰扬 发表于 2020-10-11 14:39

竟然还兼容IE。。。

zxdsb666. 发表于 2020-10-11 14:45

魔幻冰扬 发表于 2020-10-11 14:39
竟然还兼容IE。。。

我就知道会有吐槽

www.52pojie.cn 发表于 2020-10-11 15:35

百度的产品都是带漏洞的车,一边走一边漏,用户自己还得下车捡

列明 发表于 2020-10-11 15:42

魔幻冰扬 发表于 2020-10-11 14:39
竟然还兼容IE。。。

我就是在用IE11逛論壇。

然并卵zh 发表于 2020-10-11 16:10

秀呀,很像百度

丨夜愿丨 发表于 2020-10-11 17:01

nb啊 学习

魔幻冰扬 发表于 2020-10-11 17:20

列明 发表于 2020-10-11 15:42
我就是在用IE11逛論壇。

放弃IE,从你我做起{:301_992:}

moganok 发表于 2020-10-11 18:35

这些问题我几年前就解决过,基本上源代码修补。。。。。
页: [1] 2
查看完整版本: 百度编辑器的那些坑