CSP:拒绝执行内联脚本

Scr*_*amX 5 javascript jquery nonce content-security-policy

我究竟做错了什么?由于某种原因,CSP 无论如何都会阻止 js 文件调用,即使我在 attr 中指定了随机数 ID。

<head>
    <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-Xiojd98a8jd3s9kFiDi29Uijwdu';">
</head>
Run Code Online (Sandbox Code Playgroud)

通话功能:

jQuery.loadScript = function (url, callback) {

jQuery.ajax({
        url: url,
        dataType: 'script',
        success: callback,
        async: true,
        scriptAttrs: { nonce: "Xiojd98a8jd3s9kFiDi29Uijwdu" }
    });
}

$.loadScript("/js/temp.js");
Run Code Online (Sandbox Code Playgroud)

错误信息:

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'nonce-Xiojd98a8jd3s9kFiDi29Uijwdu'”。启用内联执行需要“unsafe-inline”关键字、哈希值(“sha256-9pSu4Q2RG6fzg6RdmNxg1z3W+Y9EdC0f​​90RGYsLO/o4=”)或随机数(“nonce-...”)。

Jquery 版本: /*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */

编辑:如果我不使用$.loadScript函数,所有安装了nonce attr的js文件都可以正常工作。问题出在js文件的动态调用上,但不幸的是我无法摆脱它。并且需要动态加载。

编辑(2):我尝试通过 document.createElement ("script"),也通过 jQuery.globalEval 并在各处添加随机数。输出结果表明某些函数(其中一个使用 foreach)无法运行并出现错误:Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'nonce-Xiojd98a8jd3s9kFiDi29Uijwdu'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. 通过“网络”选项卡中的控制台,我看到了加载的脚本。

不工作 --->

jQuery.globalEval($.loadScript("/js/temp.js"), {
    nonce: "Xiojd98a8jd3s9kFiDi29Uijwdu"
});
Run Code Online (Sandbox Code Playgroud)

不要再工作了 --->

var scriptTag = document.createElement("script");
scriptTag.type = "text/javascript";
scriptTag.src = "/js/temp.js";
scriptTag.setAttribute("nonce", "Xiojd98a8jd3s9kFiDi29Uijwdu");
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(scriptTag);
Run Code Online (Sandbox Code Playgroud)

如果我删除元内容安全策略 - 上面的所有代码都有效。所有脚本都根据需要工作)

Scr*_*amX 0

问题很简单。感谢 jquery 开发人员。事实证明,一开始一切都很清楚,但我只是没有注意到,因为我的代码太大了。问题出在 DOM onevent 处理程序中,在我的例子中,问题出在 DIV 上的 onclick 事件中。

<div onclick="setContent('content1')">1</div>
Run Code Online (Sandbox Code Playgroud)