我有一个 Web 界面,它使用 JavaScript 函数使用 Web 服务器创建的 data-* 属性中的数据来创建 html 元素。该函数将由复选框的 onchange 事件触发。
java脚本函数和添加事件监听器的部分都在外部静态java脚本内。使用 defer add_event_listener 将在页面加载完成后触发。
我的问题是,如何更改脚本,以便内容安全策略带有 script-src: 'self';有效,无需“不安全内联”来避免 XSS 攻击?
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; style-src 'self'">
</head>
<body>
<script src="./script.js" defer></script>
<div id="data-display">hi</div>
<label for="radio-1">radio-1
<input class="radio-1" id="radio-1" name="radio" value="1" type="radio">
</label>
<label for="radio-2">radio-2
<input class="radio-1" id="radio-2" name="radio" value="2" type="radio">
</label>
</body>
</html>
将元标记内容更改为 content="script-src 'unsafe-inline' 'self'; style-src 'self'" 以避免错误: “该页面的设置阻止了事件处理程序 (script-src-attr) 的执行,因为它违反了以下指令:“script-src 'self'”
function changeData(data) {
var data_display = document.getElementById('data-display');
data_display.innerHTML = '';
p = document.createElement("p");
p.innerText = data;
data_display.appendChild(p);
}
document.querySelectorAll('.radio-1').forEach( (element) => {
element.setAttribute("onchange", "changeData('hi radio')");
});
我正在考虑在服务器端生成所有这些 html 元素,并将它们隐藏。 仅使用 JavaScript 使它们可见。 问题是:我将有 20 到 30 个不同但相似的 div 来显示/隐藏,这是浪费的。 我希望有更优雅的解决方案。
我已经在 Windows 11 的 Chrome、Edge 和 Firefox 中测试了您的代码。我只能在 Firefox 中重现您报告的错误。
这可能是一个错误,也可能是一个功能,我无法判断,但我确实知道解决方案:
而不是使用以下方式更改 DOM:
element.setAttribute("onchange", "changeData('hi radio')");
您可以像这样附加一个事件处理程序:
element.addEventListener("change", function (event) {
changeData("hi radio");
});
Firefox 喜欢这样,而且这是更好的方法。