织梦后台编辑器禁止粘贴样式

问题背景

织梦 DedeCMS 后台默认集成的是 ckeditor 编辑器,编辑从 Word、Excel 或其他网页复制的文本时,会原样保留外部样式,包括 font 标签、行内 style、class、span 嵌套等。这些冗余代码不仅让数据库中 article 表的 body 字段体积迅速膨胀,还会导致前台模板样式被外部样式覆盖,造成排版混乱、移动端字号异常等问题。

因此,对编辑器做粘贴样式过滤、强制以纯文本或受控格式入库,是织梦内容维护中很有必要的环节。

原因分析

ckeditor 默认粘贴策略

织梦早期版本(5.7 SP2 及之前)所带的 ckeditor 默认配置 CKEDITOR.config.pasteFilter 没有显式开启,对粘贴进来的内容做轻量清洗,但保留了大部分内联样式。Word 粘贴时还会触发 pastefromword 插件,进一步把 Word 特有的 mso-* 样式带入正文。

visible 标签污染正文

常见的污染标签包括:font、span(带 style)、p(带 mso-*)、table(带 width、border、cellpadding 等旧式属性)。这些在前台响应式模板下都会破坏自适应布局。

解决步骤

一、定位编辑器配置文件

织梦默认编辑器的 ckeditor 配置主要在以下两个位置:

/include/ckeditor/config.js
/dede/templets/article_add.htm
/dede/templets/article_edit.htm

其中 config.js 是全局配置,article_add.htmarticle_edit.htm 里通常以 CKEDITOR.replace('body', {...}) 形式传入实例参数,会覆盖全局配置。

二、开启强制纯文本粘贴

config.js 中追加以下配置:

CKEDITOR.editorConfig=function( config ) {
    // 强制粘贴为纯文本
    config.forcePasteAsPlainText=true;
    // 粘贴过滤器
    config.pasteFilter='semantic-content';
    // 禁用 pastefromword 插件
    config.removePlugins='pastefromword';
    // 允许的标签白名单
    config.allowedContent='p br strong em u s; a[!href,target]; img[!src,alt,width,height];' +
        'ul ol li; table tbody tr td th; h2 h3 h4; blockquote';
    // 禁止带 style/class/align 等属性
    config.disallowedContent='style *[style]{*}; *[class]{*}; *[align]';
};

三、在 article_add/edit 模板里同步设置

由于后台模板内 CKEDITOR.replace 会覆盖全局 config,因此需要在该调用里同样加上:

CKEDITOR.replace('body', {
    forcePasteAsPlainText : true,
    pasteFilter : 'semantic-content',
    allowedContent :
        'p br strong em u s; a[!href,target]; img[!src,alt,width,height];'+
        'ul ol li; table tbody tr td th; h2 h3 h4; blockquote'
});

四、用 JS 拦截粘贴事件兜底

对于已自带 oldWord 粘贴的版本,可监听粘贴事件做二次过滤:

CKEDITOR.on('instanceReady', function(e){
    e.editor.on('paste', function(ev){
        var html=ev.data.dataValue;
        // 去掉 font/span/style 标签及 mso 样式
        html=html.replace(/<(font|span|style)[\s\S]*?>/gi,'')
                   .replace(/<\/(font|span|style)>/gi,'')
                   .replace(/\s*(class|style|align|color|face|size)\s*=\s*("[^"]*"|'[^']*')/gi,'')
                   .replace(/mso-[^;]+;?/gi,'');
        ev.data.dataValue=html;
    });
});

配置示例汇总

推荐做法:以 allowedContent 白名单 + forcePasteAsPlainText 为主,事件拦截作为兜底,三者结合后基本能保证入库内容干净。

注意事项

  • 修改前务必备份 /include/ckeditor/config.js/dede/templets/article_*.htm,避免误删原有 toolbar 配置。
  • 升级 DedeCMS 或迁移站点时,ckeditor 目录通常会被覆盖,配置需重新同步。
  • 白名单中尽量不要开放 divspan,否则极易被粘贴内容再次污染。
  • 表单二次提交或使用 UEditor 替换 ckeditor 的站点,需要在 UEditor 的 ueditor.config.js 中设置 pasteplain:true
  • 过滤后前台若发现图片被剔除,请检查白名单是否包含 img[!src]

后续建议

粘贴样式过滤上线后,建议对历史 body 字段做一次批量清洗(用 SQL 配合 REGEXP_REPLACE 或 PHP 脚本),清除旧数据中的 font/span 残留。同时把 config.js 纳入版本管理,避免下次升级丢失配置,让站点长期保持干净的内容结构,对百度收录与移动端体验都是正向加分。