如何将格式化HTML正确加载到CKEditor 5而非显示原始标签
嘿,我一眼就看出问题出在哪了——是Razor视图的自动HTML编码在搞鬼!
当你在JS代码里直接写'@Model.MailTemplate.MailTemplateData'时,Razor为了防止XSS攻击,会自动把原始HTML里的<、>这类特殊字符转义成<、>。这就导致CKEditor拿到的不是真正的<b>或<br/>标签,而是已经被转义后的字符串,自然会把这些标签当成普通文本显示,而不是解析成格式化的效果。
解决办法其实很简单,分两步走:
1. 让Razor输出原始HTML内容
在Razor视图中,要用Html.Raw()方法来输出未被编码的原始HTML字符串,这样JS才能拿到正确的标签内容。
把你原来的JS代码里的内容替换成:
// 简化版:直接用setData加载(推荐) theEditor.setData('@Html.Raw(Model.MailTemplate.MailTemplateData)'); // 如果你坚持用toView/toModel的流程,也要改成: const viewFragment = theEditor.data.processor.toView('@Html.Raw(Model.MailTemplate.MailTemplateData)'); const modelFragment = theEditor.data.toModel(viewFragment); theEditor.model.insertContent(modelFragment, theEditor.model.document.selection);
2. (可选)处理编辑器初始内容
如果你之前尝试过取消注释@Model.MailTemplate.MailTemplateData让编辑器直接加载初始内容,同样要改成@Html.Raw(...),否则初始内容也会是转义后的标签:
<div class="document-editor__editable"> @Html.Raw(Model.MailTemplate.MailTemplateData) </div>
不过其实用setData方法的话,完全可以保持这个容器为空,因为setData会覆盖掉初始内容,不用重复处理。
为什么之前的操作没用?
你之前写的toView转toModel的流程本身是正确的,但架不住传入的字符串已经被Razor转义了啊!比如原本的<b>This is a test</b>被转成了<b>This is a test</b>,CKEditor拿到这种内容,只能把它当成普通文本渲染,自然就显示成你看到的“原始标签”样子了。只有当传入的是未编码的原始HTML时,CKEditor的处理器才能正确识别标签并转换成对应的格式化内容。
内容的提问来源于stack exchange,提问作者Ev Conrad

