Vue里用innerHTML显示用户评论内容,怎么防止XSS攻击啊?

书生シ竞兮 阅读 165

我在做一个论坛帖子的评论展示功能,用v-html渲染用户提交的内容,但测试时发现能直接执行脚本标签。比如用户输入alert(1),页面真的会弹窗。试过用转义函数替换尖括号,但图片和链接标签也失效了,怎么办?

代码是这样的:


<template>
  <div v-for="comment in comments">
    <div class="comment-content" v-html="comment.content"></div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const comments = ref([
  { content: '<p>测试内容</p><script>alert(1)</script>' }
])
</script>

用v-html直接显示确实方便,但这样风险太大了。转义后用户输入的格式化标签也没法用了,有没有既能保留HTML格式又安全的方法?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
Mr-光纬
Mr-光纬 Lv1
用v-html渲染用户输入的内容确实方便,但直接渲染等于把安全责任全推给前端,太危险了。我之前也踩过这个坑,推荐用一个专门处理HTML安全的库,比如DOMPurify。

import { ref } from 'vue'
import DOMPurify from 'dompurify'

const comments = ref([
{ content: '<p>测试内容</p><script>alert(1)</script>' }
])

function sanitizeHtml(dirty) {
return DOMPurify.sanitize(dirty)
}


模板里这么写:<div v-html="sanitizeHtml(comment.content)"></div>。这样既能保留正常的HTML格式,又能过滤掉恶意脚本,省心又靠谱。别再自己写转义函数了,容易漏掉特殊情况,DOMPurify这种库就是干这个的,比你我写的都全。
点赞 1
2026-02-18 23:04
端木淑宁
v-html确实方便,但直接渲染用户输入的内容就是个大坑,分分钟被XSS攻击。你提到的转义函数虽然能防住脚本执行,但把正常HTML也干掉了,这事儿得换个思路。

推荐用一个叫 dompurify 的库,专门清理用户输入的HTML内容,既能去掉危险标签和属性,又能保留正常的格式化内容,比如图片、链接啥的。这样更清晰,安全性也有保障。

安装它很简单:
npm install dompurify


然后在代码里稍微改一下:
<template>
<div v-for="comment in comments">
<div class="comment-content" v-html="sanitizeHtml(comment.content)"></div>
</div>
</template>

<script setup>
import { ref } from 'vue'
import DOMPurify from 'dompurify'

const sanitizeHtml = (html) => DOMPurify.sanitize(html)

const comments = ref([
{ content: '<p>测试内容</p><script>alert(1)</script>' }
])
</script>


DOMPurify.sanitize 会自动清理掉危险的部分,比如