首页 / 资讯中心 / 文章详情

UEditor公式插件部署排错:版本对齐与公式回显实战

UEditor公式插件部署排错:版本对齐与公式回显实战 ★ FEATURED ARTICLE
简介面向需要在网页富文本编辑场景中录入数学公式的开发者这份资源提供UEditor编辑器与kityformula-plugin公式插件结合的完整前端文件适用于教育题库、在线作业、课程笔记等图文公式混排页面。压缩包共747个文件、约3.43MB以png图标、js脚本、gif与jpg素材、html页面和css样式为主并附带woff/eot/ttf字体及svg等辅助资源覆盖编辑器核心脚本、皮肤、图标与公式插件依赖目录结构便于按模块检索和替换。已有1463人学习下载在富文本公式编辑集成场景中具备一定参考价值。拿到后可查看静态资源的组织方式快速嵌入现有Web项目也可作为教学演示与二次开发的基础模板按需裁剪语言包、皮肤与插件文件并对照样式和依赖关系排查加载失败、图标缺失或公式渲染异常等问题减少从零配置编辑器与公式插件的时间。1. 先看清这套环境UEditor 编辑器加公式插件版本对不上比装不上更折腾一个题库后台交付到第三周前端同事把 UEditor 编辑器打开给我看文字能打、图片能传、加粗也正常唯独工具栏里那个公式按钮点下去弹窗一片空白。这类“半残”的 UEditor 编辑器我一年能碰上七八个问题从来不在编辑器本身而是公式插件那套依赖没跟主包对齐。UEditor 编辑器本身只是个纯前端壳子真正的公式输入能力来自 kityformula 这套公式插件它又连带依赖一份 MathQuill 和一套资源目录。版本错位之后编辑器能打开、能保存、能显示就是公式出不来这种“看起来装好了”的状态最难排查翻车往往就翻在这里。下面按我实际部署一遍的顺序来先定版本再落目录再接插件最后处理保存和回显。2. 落地前的版本与目录UEditor 1.4.3.3 主包怎么解压、放哪、改哪动手之前先把版本固定下来这一步省不得。UEditor 官网放出的包有 UTF-8 和 GBK 两套编码又按后端语言分了 php、jsp、net 三个目录选错编码会直接导致中文 lang 文件乱码、弹窗标题变问号。我踩过一次为了“省事”拿了一个 GBK 包结果前端页面是 UTF-8编辑器里的“插入公式”文案全变成方块排查了半天才反应过来是文件编码问题这就是典型的装完能跑、但用起来处处别扭。所以下面所有步骤都建立在同一个基准上UEditor 1.4.3.3 UTF-8 主包配同批次发布的 kityformula 公式插件。2.1 版本对照主包、公式插件、渲染库各用哪个这套环境里一共四个东西需要版本对齐主包决定壳子和弹窗骨架kityformula 决定公式按钮点开之后长什么样MathQuill 是弹窗里那个可视化公式输入框的底层MathJax 负责前台把公式渲染成人能看的排版。它们不是同一个团队维护的所以版本组合需要自己定。组件建议版本作用版本取舍说明UEditor 主包1.4.3.3 UTF-8编辑器壳子、工具栏、弹窗框架公式插件对 1.4.3.3 的适配最完整往上没有官方新版往下弹窗 DOM 结构差异大后端语言包与主包同批的 php / jsp / net 目录处理上传、输出 config.json必须和主包同批次跨批次 controller 路由对不上kityformula-plugin与主包同批发布版公式可视化编辑用 all-min 压缩版省掉单独引 kity 核心的麻烦MathQuill0.10.1弹窗内公式输入框0.10.x 与 kityformula 的接口稳定0.12 之后 API 有变动MathJax2.7.9 或 3.x前台展示态渲染2.7.9 默认支持$...$3.x 默认只认\(...\)迁移时容易漏配版本选定之后就别再动尤其不要把 MathJax 从 2.x 随手升到 3.x。3.x 的配置对象结构完全变了MathJax.Hub.Queue这套写法全部失效前台看着公式不渲染控制台又不报明显错误很容易被当成编辑器的问题去查白白浪费半天。2.2 解压与目录落位静态资源目录怎么摆解压之前先确认静态资源目录是可写的并且 web 服务器对它有读权限。我习惯把整个 ueditor 目录放在应用自己的静态资源下而不是扔到根目录这样部署到子路径、或者前面挂一层路由转发时路径推导不会出错。# 解压到应用静态资源目录解压后目录名是 utf8-php先改成语义化的 ueditor unzip ueditor1_4_3_3-utf8-php.zip -d /var/www/app/static/ mv /var/www/app/static/utf8-php /var/www/app/static/ueditor # 确认关键文件都在缺一个后面都要返工 ls /var/www/app/static/ueditor/ # 期望看到ueditor.config.js ueditor.all.min.js lang/ dialogs/ plugins/ php/或 jsp/ net/ # 给 web 用户读权限写权限只给上传目录 chown -R www-data:www-data /var/www/app/static/ueditor chmod -R 755 /var/www/app/static/ueditor chmod -R 775 /var/www/app/static/ueditor/php/uploadchmod那两行的差别值得说一下静态资源目录只需要读和执行权限755足够真正需要写权限的只有后端语言包下的 upload 目录公式插件本身不需要写入磁盘。有人图省事把整个 ueditor 目录设成777短期能跑长期是个隐患上传目录被塞进脚本文件也不是没发生过。落位之后第一个要改的是ueditor.config.js顶部的路径变量。这个值决定了编辑器去哪个地址加载弹窗 HTML、语言包和插件脚本是整篇文章里最容易写错的一行。// ueditor.config.js 顶部必须在其他配置之前 window.UEDITOR_HOME_URL /static/ueditor/;这里有两个细节末尾的斜杠不能省编辑器内部是直接拼接字符串的少了斜杠就会拼出/static/ueditordialogs/formula/formula.html这种地址另外如果你的应用部署在子路径下比如/admin/那这个值要写成/admin/static/ueditor/否则弹窗加载 404点公式按钮就是一片白。2.3 后端语言包与 config.json 连通性UEditor 的后端不复杂它靠一个 controller 入口按action参数分发请求actionconfig时返回一份 JSON 配置actionuploadimage之类时处理上传。公式插件本身不走上传但编辑器初始化时会请求一次 config这条链路不通编辑器能显示但功能会一片灰。# 直接打后端入口看能不能拿到 JSON curl -s http://127.0.0.1:8080/static/ueditor/php/controller.php?actionconfig | head -c 300能返回一段以{开头的 JSON说明后端通了返回 404 说明路径不对返回 PHP 源码说明 web 服务器没配 PHP 解析返回 500 基本是语言包目录权限或者 PHP 版本问题。这一步不要跳过很多“公式按钮没反应”的问题根因就在这个请求根本没成功。3. 公式插件接入toolbar 加按钮、弹窗挂资源、配置项对齐主包能跑之后才轮到公式插件。这一章是整套环境的核心三件事必须同时成立工具栏里有formula按钮、弹窗能加载出 kityformula 的编辑界面、config.json 里的上传参数不会影响编辑器初始化。少任何一件表现出来都是“公式用不了”但修法完全不同。3.1 toolbar 数组改造把 formula 放进工具栏UEditor 的工具栏是纯配置驱动的toolbars是个二维数组外层是行、内层是按钮名。formula这个按钮名是插件注册的写错一个字母就不会显示比如写成formulas或者Formula都无效而编辑器不会报任何错。// 初始化编辑器重点是 toolbars 里显式带上 formula var ue UE.getEditor(editor, { // 二维数组外层每一行是一排按钮太挤可以拆成两行 toolbars: [[ fullscreen, source, undo, redo, bold, italic, underline, forecolor, fontsize, link, unlink, insertimage, attachment, emotion, formula, inserttable, pagebreak ]], // 关掉自动长高避免公式块把编辑器撑得太高 autoHeightEnabled: false, // 初始高度按业务给题库类表单一般 400 往上 initialFrameHeight: 420, // 上传接口地址留空则走后端语言包默认入口 serverUrl: });formula放在哪一排不影响功能但影响使用体验它属于高频插入类按钮和图片、附件放一排比较顺手。autoHeightEnabled: false是我在题库场景下的固定做法公式块高度差异大自动长高会让页面滚动条疯狂跳动用户以为页面卡了。还有一点toolbars如果整个不写UEditor 会用默认工具栏默认里是没有formula的。所以不能指望“默认应该有”必须显式列出来。3.2 公式插件三处挂载js、css、资源目录kityformula 不是简单引一个 js 就完事它有三处需要落到正确位置否则弹窗打开是空壳。常见做法是把自己下载的 kityformula 解压后整体覆盖进dialogs/formula/目录让弹窗 HTML 里原有的相对路径能直接命中。落位文件目标路径缺失后的表现kityformula-plugin-all-min.jsstatic/ueditor/dialogs/formula/kityformula/点按钮无反应控制台提示 kity 未定义kityformula.css同上目录弹窗能开但公式输入框样式全乱按钮错位assets 资源目录同上目录下的assets/公式符号图标不显示输入区一片空白formula.html 弹窗static/ueditor/dialogs/formula/formula.html点按钮弹窗 404 或空白然后在前端页面按顺序引入这个顺序不能随便调!-- 1. 先引 UEditor 配置再引主包最后引语言包 -- script src/static/ueditor/ueditor.config.js/script script src/static/ueditor/ueditor.all.min.js/script script src/static/ueditor/lang/zh-cn/zh-cn.js/script !-- 2. 公式插件样式必须在插件 js 之前否则首屏会闪一下无样式 -- link relstylesheet href/static/ueditor/dialogs/formula/kityformula/kityformula.css !-- 3. 公式插件本体必须放在 ueditor.all.min.js 之后 -- script src/static/ueditor/dialogs/formula/kityformula/kityformula-plugin-all-min.js/scriptkityformula-plugin-all-min.js这个 all 版本已经把 kity 核心、MathQuill 适配层打包进去了所以不用再额外引kity.min.js和mathquill.min.js。反过来如果你用的是非 all 的拆分版本那就得按 kity 核心、mathquill、kityformula 三层的顺序引顺序错一个就报未定义。这也是我更推荐 all 版的原因少三行代码少三种出错可能。3.3 config.json 参数对齐别让上传配置带崩编辑器公式插件本身不产生上传请求但编辑器初始化会统一读一遍 config.json如果这份 JSON 写坏了整个编辑器初始化就会中断表现是工具栏渲染到一半停住公式按钮自然也没有。所以这份配置要当成基础设施来对待。{ imageActionName: uploadimage, imageFieldName: upfile, imageMaxSize: 2048000, imageAllowFiles: [.png, .jpg, .jpeg, .gif, .bmp], imageCompressEnable: true, imageCompressBorder: 1600, imageUrlPrefix: , imagePathFormat: /uploads/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6} }几个参数的实际影响imageUrlPrefix留空表示用相对路径如果前端和上传服务不同域这里要填完整域名前缀否则插入的图片全变裂图imagePathFormat里那串占位符是后端语言包自己解析的{yyyy}{mm}{dd}按日期分目录{rand:6}生成六位随机数避免重名改动这个格式时后端语言包的 upload 目录结构要同步调整不然会写到一个不存在的目录里报“上传失败”但日志里什么都没有。imageMaxSize的单位是字节2048000大约是 2M。题库场景公式多、截图多我一般会调到 5M 左右但要注意 PHP 那边的upload_max_filesize和post_max_size得跟着改只改 JSON 不改 PHP 配置大图照样传不上去。4. 公式存储与回显存 latex 还是存图片两套渲染别混公式能编辑出来之后下一个问题是存什么。kityformula 在编辑器里产出的内容形态有两种一种是内联 SVG 或者 data URI 形式的图片直接嵌在 HTML 里另一种是保留 latex 源码在标签上挂个 class前台再用 MathJax 渲染。这两种方案没有绝对优劣但混着用一定会出问题。4.1 存储格式取舍latex 与图片的对比维度存 latex 源码存内联图片 / SVG数据库体积小一段公式几十字节大一条公式几 KB 到几十 KB前台渲染依赖必须引 MathJax 或 KaTeX不依赖渲染库直接出图可编辑性高重新打开能进公式编辑器改低只能整体删掉重画缩放清晰度矢量任意缩放清晰data URI 的 SVG 清晰PNG 会糊迁移成本低文本可导出可搜索高富文本里的 data URI 很难迁移题库、试卷这种场景我一般选 latex公式要能改、要能搜、要能导出成 Word 或者别的格式存图片后面全是坑。代价是前台必须带上 MathJax页面首屏会多一个异步请求这个成本可以接受。4.2 编辑态与阅读态两套渲染策略分开写编辑器内部是 kityformula 自己管的它把公式渲染成可视化块用户点一下就能进编辑。但一旦内容被setContent回填或者在前台展示页渲染就得靠 MathJax 重新排一遍因为此时页面上只有 latex 文本没有 kityformula 的运行时。// 编辑态内容回填后必须主动触发一次排版否则公式显示成源码 ue.ready(function () { ue.setContent(rawHtmlFromServer); // MathJax 3.x 的写法返回 Promise异常要接住 if (window.MathJax MathJax.typesetPromise) { MathJax.typesetPromise([document.getElementById(editor)]) .catch(function (err) { console.error(公式渲染失败, err); }); } });// MathJax 2.7.x 的写法如果项目里还是 2.x 版本用这个 ue.ready(function () { ue.setContent(rawHtmlFromServer); if (window.MathJax MathJax.Hub) { MathJax.Hub.Queue([Typeset, MathJax.Hub, editor]); } });两段代码的区别不只是 API 名字。3.x 的typesetPromise必须传元素或者元素数组传字符串 id 也认但返回的是 Promise不接catch的话渲染失败会被静默吞掉2.x 的Queue是排队执行如果setContent之后立刻调内容可能还没写进 DOM公式会漏渲染一部分稳妥做法是放在setContent的回调里或者加一个极短的延迟。另外编辑态渲染完之后kityformula 会把纯 latex 变成可视化块这时候如果再让用户切到源码模式看到的还是 latex 原文这个体验是正常的不用去“修”。4.3 内容过滤白名单别让安全策略把公式标签吃掉这一条踩过的人最多。后端一般都会对富文本做 XSS 过滤常见做法是挂 HTMLPurifier 之类的库默认白名单里只有p、br、strong、img这些公式用的span带 class、math标签、annotation标签统统被剥掉。现象是编辑器里公式显示正常保存成功刷新之后公式没了只剩一段文字或者干脆空白。// HTMLPurifier 白名单里补上公式相关标签和属性 $config HTMLPurifier_Config::createDefault(); // 关键允许 span 保留 class 和 style公式块靠 class 定位 $config-set(HTML.Allowed, p,br,strong,em,u,span[class|style], . img[src|alt|class|style|width|height], . math,semantics,annotation[encoding],mtext,mi,mn,mo,msup,msub, . table,tr,td,th,thead,tbody,ul,ol,li,a[href|title] ); // 允许 data URI否则内联 SVG 形式的公式会被当成危险链接剥掉 $config-set(URI.AllowedSchemes, [http true, https true, data true]);HTML.Allowed是一个整体替换不是追加所以原来业务需要的标签要一并列进去别只加公式那一段否则改完之后图片、表格、链接全坏了问题比原来还大。URI.AllowedSchemes里加data是有风险的它会让所有 data URI 都放行如果你的业务允许普通用户上传任意 HTML这里要谨慎更严的做法是只在前端把公式的 data URI 转成 latex 再提交后端根本不接触 data URI。5. 排查公式插件装完没反应的五个现场这套环境的问题有个共同特征编辑器本身永远能打开出问题的都是公式那一条链路。所以排查思路是固定的从工具栏按钮是否存在往下逐层查到渲染。下面五条是我这几年遇到频率最高的按现象、原因、解决三段写对着看基本能定位。5.1 现象工具栏里找不到公式按钮现象很直观编辑器渲染正常其他按钮都在就是没有公式图标。原因基本是两个toolbars配置里没写formula或者页面加载的是另一份ueditor.config.js。第二种更隐蔽比如构建工具把配置打进 bundle 了你改的是源码目录里那份实际跑的是打包产物改完刷新毫无变化。解决方式先在浏览器里搜一下ueditor.config.js的实际请求地址确认改的文件就是加载的文件再在控制台执行UE.getEditor(editor).options.toolbars看实际生效的数组里有没有formula。如果数组里有但按钮不显示检查plugins/formula目录是否完整插件目录缺失时 UEditor 会静默跳过这个按钮。5.2 现象点公式按钮弹窗空白或者一直转圈现象是点按钮后有弹窗但里面是白的或者中间一直有个加载提示不消失。原因是弹窗 HTML 加载到了但弹窗里的 kityformula 资源路径不对。formula.html内部是按相对路径引kityformula/kityformula-plugin-all-min.js的如果你把 kityformula 放到了别的目录弹窗能开、脚本 404就表现为空白。解决方式打开浏览器开发者工具点一次公式按钮看 Network 面板里formula.html之后有没有 404 的 js 或 css 请求。按 404 的路径把文件挪到位不要改弹窗 HTML 里的相对路径那份文件是插件自带的改了下次升级就被覆盖。5.3 现象控制台报 kity is not defined 或 MathQuill is not defined现象是页面能打开控制台一片红公式相关功能全废。原因是引入顺序错了。kityformula-plugin-all-min.js依赖 UEditor 的运行时必须放在ueditor.all.min.js之后如果用的是拆分版本还要保证 kity 核心在最前面。另一种可能是用了 all 版本又额外引了拆分版两套 kity 互相覆盖。解决方式把页面里的脚本引入顺序调成「ueditor.config.js → ueditor.all.min.js → lang → kityformula-plugin-all-min.js」并且全局搜一遍有没有重复引入 kity 相关脚本。这个报错看着吓人其实最简单。5.4 现象保存后前台把公式显示成$$...$$源码现象是编辑器里公式是漂亮的排版前台页面直接显示一堆反斜杠和美元符号。原因有两个层面前台没引 MathJax或者引了但没在内容插入 DOM 之后调用排版。MathJax 是异步加载的如果在它加载完成之前就调typesetPromise会直接报未定义如果内容是通过接口异步拿到的插入 DOM 的时机也可能晚于 MathJax 初始化。解决方式把渲染调用放在内容写入 DOM 之后并且判断window.MathJax是否存在MathJax 3.x 还要注意默认分隔符只有\(...\)如果存的 latex 用的是$...$必须显式配inlineMath否则它根本不认这些公式。// MathJax 3.x 必须显式声明 $...$ 分隔符否则老数据渲染不出来 window.MathJax { tex: { inlineMath: [[$, $], [\\(, \\)]], displayMath: [[$$, $$], [\\[, \\]]] }, options: { // 跳过这些标签避免编辑器里已经排好的公式被二次处理 skipHtmlTags: [script, noscript, style, textarea, pre, code] } };5.5 现象config.json 返回 404或者编辑器初始化到一半停住现象是编辑器只渲染出一半工具栏或者干脆空白控制台有一个controller.php?actionconfig的失败请求。原因是后端语言包没有正确部署常见于把 ueditor 目录挪了位置但没改serverUrl或者 PHP 版本不兼容导致 controller 报 500。也可能是 web 服务器没给php/目录配解析规则请求打过去直接把源码返回了。解决方式先用curl直接打这个地址看返回的是 JSON、源码还是 404。返回源码就配解析规则返回 404 就核对路径返回 500 就看后端错误日志。这条链路必须通它是编辑器所有服务端功能的入口不只是上传。6. 装完怎么验证五分钟内跑通的一套验收动作装完不等于装对我习惯用一套固定动作验收全部通过才算交付。这套动作不依赖任何脚本工具一个浏览器加一个curl就够五分钟能跑完。第一步静态资源自检。在浏览器地址栏直接打开kityformula-plugin-all-min.js和kityformula.css的完整地址两者都应该返回内容而不是 404。这一步看似多余但能提前排除掉一大批路径问题比在控制台里翻 Network 快。第二步后端入口自检。用curl打一次controller.php?actionconfig确认返回合法 JSON。返回内容里至少能看到imageActionName和imageUrlPrefix两个字段没有的话说明读的不是同一份配置文件。第三步编辑器功能自检。新建一个空白页只引必要的四个脚本初始化编辑器确认工具栏出现公式按钮点开弹窗能输入公式插入后编辑器里能看到排版好的公式块。这一步排除了业务页面里其他脚本的干扰。第四步存取闭环自检。在编辑器里插一条公式随便配一段中文和一张图片提交到后端保存再刷新页面把内容回填确认公式、文字、图片三者都在。这一步最容易暴露 XSS 白名单问题公式丢了基本就是它。验收项通过标准失败时优先看静态资源js、css 均返回 200目录落位、文件名大小写后端入口返回合法 JSONweb 服务器解析规则、目录权限工具栏出现公式按钮且可点toolbars 数组、实际加载的 config 文件公式弹窗能输入并插入公式kityformula 资源路径、引入顺序存取闭环刷新后公式仍在且排版正常XSS 白名单、MathJax 渲染时机第五步兼容性抽查。这套东西在 Chrome 上基本不会出问题真正要抽的是项目实际支持的浏览器版本。如果业务还要求兼容较老的浏览器内核SVG 和 Promise 这两处要特别确认公式块可能不显示或者渲染调用直接抛异常。我一般还会在页面里加一小段自检代码方便交付后运维同事快速判断环境是否完好// 页面加载完成后做一次环境自检把结果打到控制台 window.addEventListener(load, function () { var checks { ueditor: typeof UE ! undefined, // 编辑器主包是否加载 kityformula: typeof kityFormula ! undefined, // 公式插件是否就绪 mathjax: !!(window.MathJax (MathJax.typesetPromise || MathJax.Hub)) // 渲染库是否可用 }; console.table(checks); // 三项全 true 才算环境完整任何一项 false 都按对应章节回查 });console.table这个输出方式比三行console.log直观交付时让对接人自己打开控制台看一眼就知道环境全不全省掉很多来回沟通。从那以后我每次接这套 UEditor 加公式插件的环境都强制自己先跑一遍这张验收表尤其是第三步和第四步不管多急都不跳。跳过第三步问题会拖到联调时暴露跳过第四步公式会在上线后第一批用户提交时集体消失那时候再回滚成本就高了。这套环境不难难的是每一层都以为自己装对了。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站