CSP 禁用 unsafe-inline 后 Vue 的 click 事件为啥不生效了?
我在项目里加了 Content Security Policy,去掉了 ‘unsafe-inline’,结果页面上所有 @click 绑定的事件都失效了,控制台报错说被 CSP 阻止。但我不明白为啥 Vue 的事件也算 inline?
我试过把事件逻辑移到 methods 里,还是不行。是不是因为 Vue 在编译时生成了内联 handler?下面是最简复现代码:
<template>
<button @click="handleClick">点我</button>
</template>
<script>
export default {
methods: {
handleClick() {
alert('clicked');
}
}
}
</script>
最简单的解决办法:在 CSP 里用 nonce 放行。
服务器端(以 Express 为例)生成个随机字符串:
index.html 模板里给 script 标签加 nonce 属性:
Vue 3 需要在创建 app 时配置:
实际上 Vue 3 在启用 CSP 时会自动尝试从当前 script 标签读取 nonce。
如果上面这些嫌麻烦,还有个野路子:不用 @click,改为在 mounted 里用 addEventListener 绑定事件,这样就不是 inline handler 了。