1. 从一次“换行”需求说起:为什么你的提示框不听话?
最近在做一个后台管理系统,用Vue3 + Element Plus,相信这是很多朋友的标准技术栈。那天遇到一个挺典型的需求:接口返回的成功或错误提示信息,里面包含了 <br> 标签,希望在前端的提示框里能正常换行显示。听起来很简单对吧?不就是把文本渲染出来嘛。
我一开始也是这么想的,直接用了 proxy.$modal.msgSuccess(res.msg)。结果呢?页面上弹出来的提示框里,<br> 标签被原封不动地当作文本显示了出来,变成了“操作成功
请刷新页面查看”,那个 <br> 就赤裸裸地躺在那里,别提多尴尬了。这显然不是我们想要的效果。我们期望的是“操作成功”和“请刷新页面查看”分成两行。
这个问题其实暴露了前端渲染的一个核心机制:安全过滤。Vue 和大多数现代前端框架,出于安全考虑,默认都会对动态绑定的内容进行转义处理。也就是说,你字符串里的 <、> 这些HTML特殊字符,会被转换成 <、> 这样的实体字符,从而防止它们被浏览器解析为真实的HTML标签。这是一个非常重要的安全屏障,能有效抵御最常见的XSS(跨站脚本)攻击。
所以,当你的 res.msg 里包含了 <br>,Vue 会把它当成普通的文本“<br>”来显示,而不是一个换行符。那怎么办呢?Element Plus 的 $modal.msgSuccess 这个方法,其实提供了一个“后门”参数,就是 dangerouslyUseHTMLString。听这个名字就很有警示意味——“危险地使用HTML字符串”。没错,这就是解决我们换行问题的钥匙,但也是一把需要小心保管的钥匙。
2. 揭秘 dangerouslyUseHTMLString:一把双刃剑
2.1 它是如何工作的?
我们先来看看具体怎么用。上面搜索到的原始文章里给出了一个很直接的代码示例:
getOrderInfo(_oids).then(res => {
if(res.code == 200) {
proxy.$modal.msgSuccess({
message: res.msg,
dangerouslyUseHTMLString: true
});
} else {
proxy.$modal.msgError({
message: res.msg,
dangerouslyUseHTMLString: true
});
}
});
关键就在于,我们不再直接传递一个字符串给 msgSuccess,而是传递一个配置对象。这个对象里有两个属性:message 放我们的消息内容,dangerouslyUseHTMLString 设置为 true。
当这个属性被设置为 true 时,Element Plus 内部就不会对 message 字符串进行HTML转义,而是直接把它交给浏览器的 innerHTML 属性去解析和渲染。这样一来,字符串中的 <br> 就被浏览器识别为HTML换行标签,从而实现了我们想要的换行效果。同理,你也可以使用 <strong>加粗</strong>、<span style="color: red;">红色文字</span> 等简单的HTML标签来丰富提示信息的样式。
2.2 为什么它“危险”?
这个名字绝不是危言耸听。它的危险性根植于Web安全的核心威胁——XSS攻击。我们来设想一个场景:
假设你的 res.msg 不是由你完全信任的后端接口静态返回的,而是包含了用户输入的内容。比如,一个评论系统,管理员在后台看到的操作提示是“成功删除了用户【用户输入的昵称】的评论”。如果这个昵称字段没有经过严格过滤,恶意用户可能会输入这样的昵称:
<script>alert('你的cookie是:' + document.cookie);</script>
如果后端不小心把这个昵称直接拼接到 msg 里返回,而前端又使用了 dangerouslyUseHTMLString: true,那么这段脚本就会被执行!弹窗只是最简单的演示,攻击者完全可以利用这段脚本窃取用户的登录Cookie、篡改页面内容、将用户重定向到钓鱼网站等。
即使不用 <script> 标签,利用HTML标签的事件属性也能发起攻击,例如 <img src="x" onerror="恶意代码">。所以,这个“危险”属性,实际上是绕过了Vue和Element Plus为你筑起的第一道安全防线。
3. XSS防护实战:安全地使用HTML内容渲染
知道了风险


831

被折叠的 条评论
为什么被折叠?



