You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Vue中使用v-html渲染用户代码时影响网站本身内容?

问题解决方案

你当前的实现是直接将用户输入的HTML、CSS、JS代码通过v-html插入到当前页面的DOM节点中,所有代码都运行在主站的文档上下文里,自然会出现样式污染、JS影响主站逻辑的问题。

最优解决方案是使用沙箱iframe实现预览隔离,这是目前代码编辑器预览的通用方案,能完全隔离预览内容和主站的上下文,从根源避免用户代码影响主站。


1. 修改模板部分

替换原来预览区域的v-html节点为iframe,配置sandbox属性限制权限:

<template>
  <div class="grid">
    <div id="html" class="grid-cell">
      <textarea v-model="htmlCode" name="" id="" cols="30" rows="10"></textarea>
      <div class="title">This is a cell</div>
    </div>
    <div id="css" class="grid-cell">
      <textarea v-model="cssCode" name="" id="" cols="30" rows="10"></textarea>
      <div class="title">This is a cell</div>
    </div>
    <div id="js" class="grid-cell">
      <textarea v-model="jsCode" name="" id="" cols="30" rows="10"></textarea>
      <div class="title">This is a cell</div>
    </div>
    <div id="preview" class="grid-cell">
      <!-- 替换原来的v-html节点为iframe -->
      <iframe 
        ref="previewIframe" 
        sandbox="allow-scripts" 
        class="preview-frame"
        frameborder="0"
      ></iframe>
      <div class="title">This is a cell</div>
    </div>
  </div>
</template>

sandbox属性可以根据你的需求调整权限:

  • 只保留allow-scripts:仅允许iframe内运行JS,禁止跳转、表单提交、访问父页面、读取同域存储等所有其他权限,安全性最高
  • 如需额外能力可以追加参数,比如allow-same-origin、allow-forms等,非必要不建议开启

2. 修改逻辑部分

新增监听逻辑,动态将用户代码写入iframe的独立文档中:

<script>
export default {
  name: "CodeEditor",
  data() {
    return {
      htmlCode: "<h1>hi</h1>",
      cssCode: "",
      jsCode: ""
    };
  },
  watch: {
    // 监听三个代码变量的变化,自动更新预览
    htmlCode: {
      handler: 'updatePreview',
      immediate: true
    },
    cssCode: 'updatePreview',
    jsCode: 'updatePreview'
  },
  methods: {
    updatePreview() {
      const iframe = this.$refs.previewIframe
      if (!iframe) return
      // 获取iframe的独立文档对象
      const doc = iframe.contentDocument || iframe.contentWindow.document
      // 拼接完整的预览页面代码
      const previewContent = `
        <!DOCTYPE html>
        <html>
        <head>
          <meta charset="UTF-8">
          <style>${this.cssCode}</style>
        </head>
        <body>
          ${this.htmlCode}
          <script>${this.jsCode}<\/script>
        </body>
        </html>
      `
      // 写入内容到iframe
      doc.open()
      doc.write(previewContent)
      doc.close()
    }
  }
};
</script>

额外注意事项

如果你的预览需求很简单不需要运行JS,也可以选择Shadow DOM方案实现样式隔离,但JS依然会在主站上下文执行,存在安全风险,优先推荐iframe沙箱方案。

内容的提问来源于stack exchange,提问作者user17466267

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:36:08