Vue.js v-html

🌙
手机阅读
本文目录结构

v-html

  • 预期string

详细

更新元素的 innerHTML

注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译

如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html永不用在用户提交的内容上。

单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局 <style> 元素手动设置类似 BEM 的作用域策略。

示例

<div v-html="html"></div>

参考

数据绑定语法 - 插值

xss 攻击演示

<template>
    <div id='app'>
        <div v-html='html'></div>
    </div>
</template>
<script>
export default {
    name:"app",
    data(){
        return {
            html:'<img src="https://www.axihe.com" onerror="alert(666)">'
        }
    }
}
</script>

运行之后由于 src 地址对应的资源找不到,会触发 img 标签的 error 事件,最终 alert 弹框。这便是一个最简单的 xss 攻击。

解决 html 指令存在的 xss 漏洞问题

通常我们处理 xss 攻击会使用一个 xss 的 npm 包来过滤 xss 攻击代码。

所以我们要做的就是给指令的 value 包上一层 xss 函数。有同学可能会问,我们在业务代码里使用 xss 函数处理也行。是的可以,但是我们不能保证团队每一个成员都会使用 xss 函数处理。

作为前端的架构师,我们需要从项目整体的考虑来处理这类问题,不能指望通过规范来约束团队成员。

在编译前会将我们从 vue-loader 传入的 compilerOptions.directives 和 baseOptions.directives 进行了合并。

这样我们就能覆盖 html 指令。

  1. 引入 xss 包并挂载到 vue 原型上
import xss from 'xss';
Vue.prototype.xss = xss
  1. 在 vue.config.js 中覆写 html 指令
chainWebpack: config => {
    config.module
        .rule("vue")
        .use("vue-loader")
        .loader("vue-loader")
        .tap(options => {
            options.compilerOptions.directives = {
                html(node, directiveMeta) {
                    (node.props || (node.props = [])).push({
                        name: "innerHTML",
                        value: `xss(_s(${directiveMeta.value}))`
                    });
                }
            };
            return options;
        });
}

这样我们就从源头解决了 html 指令存在的潜在 xss 攻击。

具体参考参考:https://juejin.im/post/5d5924a0e51d4561fc620a46

可能存在的问题

此外某些情况下,使用{{{}}}符号仍然不能解析 html 标签,但 v-htm 指令却可以,可能是 Vue.js 存在的 bug 。

参考:https://blog.csdn.net/farYang/article/details/53011703

其它参考

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了