
本文详细介绍了在使用EJS模板引擎渲染CKEditor生成的富文本内容时,如何避免HTML标签被转义而显示为纯文本的问题。通过对比EJS的两种输出标签`
在使用富文本编辑器(如CKEditor)创建内容时,我们通常期望最终在网页上看到的是经过格式化的文本,而不是带有HTML标签的原始字符串。然而,当将这些HTML内容传递给视图引擎(如EJS)进行渲染时,如果不了解视图引擎的默认行为,可能会遇到HTML标签被转义(escaped)的问题,导致页面上直接显示<p><strong>Lorem ipsum</strong>...</p>这样的纯文本。
EJS(Embedded JavaScript)作为一种流行的模板引擎,其设计哲学之一是默认情况下提供安全的输出。这意味着,当你使用标准的<%= variable %>语法来输出变量内容时,EJS会自动对内容中的HTML特殊字符进行转义。例如,<会被转义为,&会被转义为&等。这种机制有效地防止了跨站脚本攻击(XSS),因为恶意脚本不会被浏览器解析执行。
然而,对于从CKEditor等富文本编辑器中获取的、本身就包含合法HTML标签的内容,这种默认的转义行为就成了障碍。编辑器生成的HTML字符串,例如:
立即学习“前端免费学习笔记(深入)”;
<p><strong>Lorem ipsum</strong> dolor sit amet, consectetur adipisicing elit.<i> Quae maxime</i> dolore necessitatibus iste aliquid dolorum in nostrum repellat rerum atque?</p>
在使用<%= content %>输出后,在浏览器中会变成:
<p><strong>Lorem ipsum</strong> dolor sit amet, consectetur adipisicing elit.<i> Quae maxime</i> dolore necessitatibus iste aliquid dolorum in nostrum repellat rerum atque?</p>
浏览器将这些转义后的字符视为普通文本,因此页面上会直接显示带有尖括号的原始HTML标签。
EJS提供了一个专门用于输出未转义HTML内容的标签:<%- variable %>。这个标签告诉EJS,将变量内容作为原始HTML直接插入到模板中,而无需进行任何转义处理。
因此,要正确渲染CKEditor生成的富文本内容,只需将EJS模板中的输出语法从<%= content %>更改为<%- content %>。
示例代码:
假设你的Node.js/Express应用在路由中将CKEditor提交的内容存储在postBody变量中,并将其传递给EJS模板:
// app.js (或相关路由文件)
app.get('/post/:id', (req, res) => {
// 假设从数据库或其他地方获取到包含HTML的postContent
const postContent = "<p><strong>Lorem ipsum</strong> dolor sit amet, consectetur adipisicing elit.<i> Quae maxime</i> dolore necessitatibus iste aliquid dolorum in nostrum repellat rerum atque?</p>";
res.render('post', { content: postContent });
});在你的EJS模板文件(例如post.ejs)中,正确的写法应该是:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文章详情</title>
<!-- 引入你的CSS样式 -->
</head>
<body>
<div class="container">
<h1>文章标题</h1>
<div class="post-content">
<%- content %>
</div>
</div>
</body>
</html>使用<%- content %>后,浏览器会正确解析并渲染postContent中的HTML标签,呈现出带有粗体、斜体等格式的富文本内容。
虽然<%- variable %>解决了富文本内容的渲染问题,但使用它时必须格外小心,尤其当内容来源于用户输入时。直接输出未经处理的用户输入HTML,会带来严重的安全风险,主要是跨站脚本攻击(XSS)。
恶意用户可能会在CKEditor中输入包含JavaScript代码的HTML,例如:
<script>alert('您被攻击了!');</script>
<img src="invalid-image.jpg" onerror="alert('会话劫持!');">如果这些内容被直接用<%- ... %>输出到页面,浏览器会执行这些恶意脚本,可能导致:
安全最佳实践:
内容消毒(Sanitization): 在将用户提交的HTML内容保存到数据库之前,或在将其传递给EJS模板之前,务必进行严格的消毒处理。这意味着你需要使用一个可靠的HTML消毒库(例如dompurify for Node.js)来移除或过滤掉所有潜在的恶意标签和属性,只保留安全的HTML结构和样式。
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
// 在保存到数据库或渲染前
const cleanHTML = DOMPurify.sanitize(userSubmittedHTML);
// 然后将 cleanHTML 传递给 EJS 模板
res.render('post', { content: cleanHTML });权限控制: 仅允许受信任的用户(例如管理员)发布未经严格消毒的富文本内容。对于普通用户,即使使用CKEditor,也应该对其输入进行严格的消毒。
在EJS模板中渲染CKEditor等富文本编辑器生成的HTML内容时,关键在于理解EJS的两种输出标签:
为了确保安全,当内容来源于用户输入时,务必在输出前对HTML内容进行严格的消毒处理,以防范潜在的XSS攻击。正确选择和使用EJS的输出标签,是构建功能完善且安全的Web应用的关键一步。
以上就是在EJS模板中正确渲染CKEditor生成的HTML内容的详细内容,更多请关注php中文网其它相关文章!
HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号