前一阵子接了一个知识库站点的迁移,原站跑在标准 x86 服务器上,文章数量不大,但几乎每篇都带公式,有的是行内公式,有的是独立展示的大公式,还有一部分是带编号的复杂数学推导。迁移到国产化环境之后,后台能开、文章能读,唯独公式区域全是一堆裸的 LaTeX 源码,个别页面甚至直接白屏。排查一圈下来,问题根本不只在“公式插件怎么配”,而是整条链路——操作系统、数据库、PHP、浏览器渲染——每一层都在给 WordPress 使绊子。
这篇文章我就围绕“国产化替代中 WordPress 如何兼容信创环境公式编辑”这个真实需求,把兼容性边界、公式渲染选型、实操部署、故障排查这四块完整展开。适合正在做信创迁移的站点管理员、负责 WP 维护的开发者,以及给客户交付知识库/文档系统时会碰到数学公式场景的集成商参考。
1. 先把兼容性边界画清楚:信创环境里 WordPress 其实在四层上运行
1.1 指令集与操作系统这层最容易被忽略
很多人一听国产化迁移就觉得是换个 Linux 发行版的事,实际上信创环境里最常见的变化是 CPU 指令集和操作系统的组合不再是 x86_64 + CentOS 这种“默认答案”。
国产 CPU 里既有基于 ARM 架构的,也有自研指令集的,还有少数兼容 x86 生态的。WordPress 本身是 PHP 写的业务程序,不直接接触指令集,但它跑在 PHP 解释器上,而 PHP 解释器是编译型二进制。如果官方软件源或者第三方仓库里没有适配目标架构的 PHP 包,就得拿源码自己编译,这一步就劝退了不少人。
操作系统层面,信创环境常用的是基于 Linux 内核的国产发行版,很多发行版默认的 PHP 版本偏旧或偏新,两者都可能出问题。偏旧时 WordPress 新版要求高,直接提示 PHP 版本过低;偏新时部分老插件还带着 PHP 7 时代的写法,到了 PHP 8.x 就是一堆弃用警告甚至致命报错。
提示:动手迁移前先跑一条命令确认架构和发行版信息,再决定是直接用包管理器装 PHP,还是走源码编译。这个动作慢不了两分钟,但能省掉后面一整天的折腾。
1.2 数据库层的真实门槛不在 SQL,在字符集和协议
信创环境下的数据库选择很灵活,主流国产数据库大多提供 MySQL 协议兼容模式,这对 WordPress 来说是重大利好。因为 WP 的数据库抽象层走的就是 MySQL 语法,只要连接层能通、字符集能对齐,SQL 语句本身基本不用改。
真正容易翻车的是字符集。WordPress 官方推荐 utf8mb4,因为是真正完整的四字节 UTF-8,能覆盖生僻字、数学符号和 Emoji。公式内容里大量出现上标、下标、希腊字母、花体字母,这些字符在 UTF-8 下都能正常存,但如果数据库表一开始建成了 utf8mb3 或者 latin1,写入时就会出现“问号化”。
另一个隐藏问题是 MySQL 协议里关于排序规则(collation)的协商。WordPress 安装时会自动创建表并指定字符集,但国内不少环境在初始化数据库时改过全局字符集,导致 WP 自动建的表用了不匹配的排序规则。最典型的现象就是文章能保存,但涉及公式的中英文混检会报“Illegal mix of collations”错误。
1.3 浏览器与前端渲染层才是公式编辑的命门
公式和普通文字的最大区别是:它不能纯靠 CSS 画出来,需要专门的数学排版引擎。这就把压力带到了浏览器这一层。
信创终端上的浏览器多种多样,有基于 Chromium 内核的,也有厂商在自己内核上魔改的。不同浏览器对 JavaScript 的支持程度、对 Web Font 的加载方式、对 MathML 的渲染能力差异很大。公式插件在前端做的事,本质就是把 LaTeX 或 MathML 源码交给一个渲染库,由渲染库在浏览器里生成数学排版。
如果浏览器本身不支持某些字体格式,或者渲染库依赖的 Web API 不完整,公式就会回退成纯文本源码。更麻烦的是,很多国产浏览器默认开了“兼容模式”,对现代 JavaScript 特性支持不全,MathJax 这类库跑起来到一半就中断,白屏就是这么来的。
2. 公式编辑技术选型:MathJax、KaTeX 与浏览器原生 MathML 的取舍
2.1 三种渲染方式的原理差异
公式渲染方案目前主流的就三类,信创迁移前一定要先分清它们的本质区别。
MathJax 是历史最久、兼容性最强的方案。它的工作原理是把 LaTeX 源码先解析成内部的数学节点树,再用 HTML + CSS 和 Web Font 重新排版。好处是 LaTeX 语法支持非常全,复杂公式基本都能吃;坏处是体积大,首次渲染慢,对浏览器内存要求高。
KaTeX 走的是“极速渲染”路线。它由社区维护,把 LaTeX 子集编译成 HTML 和 CSS,渲染速度比 MathJax 快得多。但它支持的 LaTeX 语法不完整,遇到刁钻公式会直接报错或者原样输出源码,不适合重度数学内容站点。
浏览器原生 MathML 是 W3C 标准里的数学标记语言。主流现代浏览器对 MathML 的支持在逐步变好,但国产浏览器和部分旧内核浏览器对它的支持仍很随缘。如果站点的公式是简单上下标、分数、根号,MathML 够用;一旦涉及矩阵、多行对齐、分段函数这类复杂结构,原生 MathML 的渲染质量就会露怯。
| 方案 | 渲染速度 | 复杂公式支持 | 浏览器兼容性 | 信创环境适配难度 |
|---|---|---|---|---|
| MathJax 3 | 中 | 强 | 好 | 低 |
| KaTeX | 快 | 中 | 较好 | 低 |
| 原生 MathML | 依赖内核 | 弱 | 波动大 | 高 |
2.2 离线部署为什么是信创环境必选项
这里我想重点说一个实践经验:不管选 MathJax 还是 KaTeX,尽量把渲染库的 JS 和字体文件放在自己服务器上,别依赖公共 CDN。
原因很实际。第一,公式渲染库从 CDN 加载之后,浏览器要先跨域拉字体文件,一旦内网链路对境外 CDN 访问不稳定,公式就会出现“光有 HTML 骨架、没有字体渲染”的惨状。第二,信创环境的终端设备有相当一部分处于受控网络,访问公网 CDN 可能直接被策略拦截,页面其余部分加载成功,只有公式模块默默失败。第三,字体文件体积不小,每次都走 CDN 还会拖慢首屏速度。
把 MathJax 或 KaTeX 完整包部署到 WordPress 主题目录或插件目录,然后修改前端加载路径为本地地址,是最稳妥的做法。顺带把 font 目录也放到同域名下,避免跨域字体加载的麻烦。
2.3 编辑器接入:服务端存什么、前端渲染什么
公式编辑的核心,是明确服务端存的是“源码”,不是“渲染结果”。
实际项目里最稳的存储方案是:WordPress 文章内容里保存 LaTeX 源码,用短代码或自定义分隔符包起来,前端通过 MathJax 在浏览器里实时渲染。这样做的好处有三个:一是源码可编辑,作者改公式不需要重新画图;二是源码体积小,数据库存储和备份都轻松;三是换渲染引擎时不用改文章数据,只改前端逻辑。
如果站点编辑流程要求“所见即所得”,那前端还需要接一个公式输入面板。常见做法是在编辑器工具栏加一个按钮,点开弹出公式输入框,输入 LaTeX 后实时预览,确认后把源码插入文本。这里要注意一点:公式编辑面板本身只是一个输入工具,真正决定兼容性的是渲染引擎和浏览器配合,别把这两件事混为一谈。
3. 实操部署:从空服务器到公式正常显示
3.1 WordPress 内核与 PHP 环境适配
在信创环境里装 WordPress,我建议按下面的顺序来。
第一步,装 PHP。优先用发行版仓库里自带的 PHP 8.1 或 8.2。如果仓库版本过低,可以找第三方源,但要注意第三方源是否提供目标 CPU 架构的包。实在没有包,只能源码编译。编译时结合 WordPress 的实际需求,开启这几个扩展:mysqli、gd、curl、xml、mbstring、zip、bcmath。特别是 mbstring 和 bcmath 容易被漏掉,前者影响字符处理,后者某些插件会用到。
第二步,装数据库并创建空库。初始化时明确指定 utf8mb4 字符集和 utf8mb4_unicode_ci 排序规则。如果是已有数据库,也要检查全局字符集设置,别让默认 latin1 影响后续建表。
第三步,下载 WordPress 源码,解压到站点目录。然后把 wp-config-sample.php 复制为 wp-config.php,填入数据库连接信息。
第四步,也是很多新手忽略的:确认站点目录里wp-content有写权限,并且 PHP-FPM 运行用户和 Web 服务器用户一致。否则后台装插件、传主题时会遇到权限报错。
3.2 在主题中接入 MathJax 的两种方式
公式渲染库的接入方式取决于站点用的是旧版经典编辑器还是新版古腾堡块编辑器。
经典编辑器场景下,最简单的方式是往主题的functions.php里挂一个前端加载函数。核心逻辑是把 MathJax 的本地路径注册到wp_enqueue_script,再加一段内联配置指定行内公式分隔符。例如用\(...\)表示行内公式,\[...\]表示独立公式,这样编辑文章时直接输入 LaTeX,前端就会自动渲染。
古腾堡编辑器场景下,更推荐用支持短代码兼容的插件方案,或者直接在文章/页面自定义 HTML 块里插入 LaTeX 源码。关键点是要关闭古腾堡对短代码内容的自动转义,否则 LaTeX 里的大量反斜杠会被转成 HTML 实体,最终渲染出来全是乱码。
这里给出一个最基本的 functions.php 接入形状,实际部署时替换成本地路径即可:
function theme_enqueue_mathjax() { if (!is_admin()) { wp_enqueue_script( 'mathjax', get_template_directory_uri() . '/assets/js/mathjax/tex-svg.js', array(), '3.2.2', true ); wp_add_inline_script('mathjax', 'MathJax = { startup: {pageReady: function() {} } };', 'before'); } } add_action('wp_enqueue_scripts', 'theme_enqueue_mathjax');这段代码里的关键动作不是脚本加载本身,而是wp_add_inline_script把全局配置对象提前注入,MathJax 启动时会读取这个对象。如果漏掉这一步,MathJax 会沿用默认配置,行内公式分隔符不生效,公式依然不会渲染。
3.3 数据库字符集与 wp-config.php 关键配置
数据库层面最容易踩的坑就是排序规则不一致。我这里提供一个可靠的核对方法。
建库之后,用数据库客户端执行一段查询,检查目标库的默认字符集:
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'your_database';如果查出来的DEFAULT_CHARACTER_SET_NAME不是 utf8mb4,就在 wp-config.php 里显式加上:
define('DB_CHARSET', 'utf8mb4'); define('DB_COLLATE', 'utf8mb4_unicode_ci');这两个常量会告诉 WordPress 使用什么字符集建立连接和创建表。只改数据库不改 wp-config.php 也是白搭,因为 WordPress 的数据库驱动在建立连接时会先读这两个常量。
另外建议在 wp-config.php 里顺手加上内存上限调整。公式多的页面,MathJax 在浏览器端占内存,但 PHP 侧在生成预览、处理短代码时也吃内存,尤其是有公式缓存重建的场景:
define('WP_MEMORY_LIMIT', '256M');3.4 渲染验证与缓存策略
公式部署完成后,至少要验证四类场景:单层行内公式、独占一行的独立公式、带数组/矩阵的复杂公式、以及公式和中文混排的段落。每一类都要在目标信创浏览器上过一遍。
如果站点开了页面缓存,公式场景还要特别注意:MathJax 渲染是浏览器端行为,缓存一般不会影响公式内容,但如果缓存的是服务端直出的 HTML,而这段 HTML 里嵌了太多实时注入的脚本片段,就可能在缓存命中时出现“脚本加载顺序错乱”。我的处理建议是:对纯公式文章关闭页面级缓存,或者把渲染库脚本改成固定版本路径并加入缓存指纹。
4. 高频故障排查:公式不显示、乱码、白屏的现场解法
4.1 一张速查表解决 80% 的问题
| 现象 | 常见原因 | 解决方向 |
|---|---|---|
| 公式显示为 LaTeX 源码 | 渲染库未加载或配置未生效 | 检查前端 JS 路径,确认 inlines 配置 |
| 公式区域空白,无源码无公式 | MathJax 脚本执行报错 | 打开浏览器控制台看 JS 异常,验证是否为兼容模式 |
| 公式中的字母是方框或乱码 | 字体文件未加载或字体格式不被识别 | 确认字体路径为本地,检查 font 目录能否直接访问 |
| 文章保存后反斜杠增多 | 古腾堡编辑器对内容进行了转义 | 改用短代码包裹,或关闭自动平衡标签 |
| 页面中文正常,公式单独乱码 | 数据库字符集非 utf8mb4 | 调整 DB 字符集,重建对应表 |
| 后台编辑正常,前台不显示 | 页面缓存了旧版本 JS | 清理缓存,确认缓存插件不排除公式脚本 |
| PostgreSQL 等非 MySQL 数据库报错 | 数据库协议不兼容 | 尽量用 MySQL 兼容模式,避免改造 SQL |
这七种情况覆盖了信创环境里绝大多数公式类问题。如果表格命中不了,再走下面的深度排查。
4.2 一次白屏问题的完整排查过程
我印象比较深的一次:站点在开发机上公式渲染完美,迁移到目标信创终端后,只要进入带公式的页面就直接白屏,刷新也没用。
第一步,我先在浏览器开发者工具里看控制台。报错信息指向 MathJax 内部一个“不支持的目标结构”错误,看起来是渲染某个矩阵元素时挂了。单独看代码逻辑有点懵,于是第二步我做了最小复现:新建一个空白页面,只放一个最简单的公式\(a^2+b^2=c^2\),渲染正常。再逐步加入复杂公式,定位到是一段含\begin{matrix}的公式触发错误。
第三步,查看站点启用的 MathJax 版本,发现是旧版 2.x 的入口文件,旧版加载器对某些配置项的处理方式和新版不同。最终把入口统一切到 MathJax 3 的 tex-svg 现代组件,问题解决。
这里想强调一件事:出现白屏时别急着怀疑 WordPress,先在浏览器里单独打开渲染库脚本的 URL,确认它是否正常返回。如果返回正常,再检查脚本运行时的报错信息。大多数所谓“兼容性问题”,最后都能定位到版本太旧或配置冲突。
4.3 排查公式问题时最高效的三个动作
第一个动作是“按 F12 看网络请求”。重点看渲染库脚本和字体文件是否加载成功,如果字体请求挂了,就基本锁定是路径问题而不是逻辑问题。
第二个动作是“在控制台手动执行渲染初始化”。很多前端公式渲染库支持手动触发转换,这样能把“页面自动初始化失败”和“脚本执行异常”两个问题区分开。如果能手动渲染成功,说明脚本本身活着,问题出在初始化时机或配置注入时机;如果手动也失败,就往脚本版本和浏览器兼容性方向查。
第三个动作是“临时禁用页面优化插件”。公式类脚本经常和 JS 合并、延迟加载、defer 等优化策略打架。临时关掉优化类插件,如果公式恢复正常,再一个个开启插件定位冲突点。
5. 踩坑记录与长期维护建议
5.1 三个我至今记忆深刻的坑
第一个坑是“以为公式是纯前端问题”。早期做迁移,我把所有精力放在改编辑器、调 MathJax 配置上,结果某页面的公式始终保存不了。后来查数据库日志才发现,报错是字段内容超过 mediumtext 长度限制。一篇里面有几十个复杂公式的文章,源码长度轻松超过 64KB。解决办法是手工把对应字段改成 longtext,才算彻底根治。这件事之后我再看公式站点,第一反应是先确认数据库字段类型。
第二个坑是“字体预加载过度”。为了让公式首屏更快,我尝试把所有字体文件提前 preload,结果不但没变快,反而因为 preload 一个很大的 woff2 文件阻塞了页面渲染关键路径,体感越优化越慢。后来学乖了,让 MathJax 按需加载字体,把真正常用的字体子集单独拷贝出来,首屏速度明显改善。
第三个坑是“版本锁定没做”。MathJax 这类前端库升级频率不高,但一升级就容易破坏公式解析规则。我之前在某次内容维护时顺手更新了库版本,结果旧文章里大量使用自定义宏定义符号的公式全部失效。现在我会把渲染库固定在一个明确版本,只在测试环境验证过再升。给客户的交付文档里也会写明白:渲染库版本和 WordPress 版本一样,属于生产关键依赖,不能随手升级。
5.2 长期维护的注意点
信创环境的一个显著约束是软件包的更新节奏和公网生态不完全同步。所以建议把公式渲染所需的静态资源做一次完整归档,包括 JS 入口、字体文件、配置样例,全部放到版本控制仓库里。将来服务器重建或者迁移到另一台信创节点时,直接拉取归档,比去公网下载更可控。
内容创作侧的公式习惯也需要标准化。我整理团队写作规范时会要求三条:公式统一使用 LaTeX 源码存储;行内公式用\(...\)包裹,独立公式用\[...\]包裹;不在公式里混合使用 HTML 标签。这三条看起来简单,能避免大量后续脏数据。
缓存策略方面,如果站点有 CDN 或反向代理,要注意缓存键是否区分“完整版”和“纯净版”两种页面变体。有些优化插件会为移动端和桌面端生成不同 HTML,公式字体路径在两种变体里不同,缓存键不区分的话,就会偶发桌面端串出移动端的异常样式。
5.3 一点实际的心得
我在给不同信创环境做公式站点适配时发现一个规律:真正拖后腿的往往是基础设施层面的小细节,而不是公式渲染库本身。公式渲染技术已经很成熟,难点集中在 PHP 扩展缺失、字符集不统一、本地字体资源不完整、浏览器兼容模式未关闭这些“听起来很小”的问题上。做信创迁移,最忌讳的是抱着“换台服务器就行”的心态,一定要把 WordPress、数据库、前端渲染三层当作一个整体来验收。
最后再分享一个小技巧:迁移完成后,用脚本批量扫描所有历史文章,找出没有被公式包裹标记但仍包含\frac、\sum、\int等 LaTeX 特征词的段落,排查是否有遗漏的裸源码。这种扫描不复杂,却能快速定位迁移过程中被漏掉的公式内容。公式站点的价值全在内容本身,如果历史文章有一批显示成了源码,用户对整站信任度的打击比想象中大得多。