【发布时间】:2020-12-24 12:41:19
【问题描述】:
期望的行为
在我的 webpack 捆绑 js 文件中加入 reCaptcha JavaScript 代码,而不是通过内联脚本标签。
实际行为
我在 Chrome 开发工具中收到此错误:
Uncaught ReferenceError: grecaptcha is not defined
我的尝试
以下inline 实现有效,我一直在使用these docs for reference。
但是,我必须将 unsafe-inline 添加到我的 script-src 内容安全策略中才能允许内联脚本运行。更具体地说,这是通过onLoadCallback 函数实现explicit rendering 所必需的。
Google 有一个FAQ about CSP and reCaptcha,但它只适用于automatic rendering,没有回调函数或defined parameters。
我宁愿不必使用内联脚本。
index.html
<head>
<script type="text/javascript">
var onloadCallback = function() {
grecaptcha.render('g-recaptcha', {
'sitekey': '******',
'size': 'compact'
});
};
</script>
</head>
<body>
<div id="g-recaptcha"></div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
</body>
</html>
但是,当我尝试像这样将 JS 添加到我的 entry.js 文件中时(停止使用内联脚本):
index.html
<head>
<script type="module" src="/js/bundle.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
</head>
<body>
<div id="g-recaptcha"></div>
</body>
</html>
entry.js
const onloadCallback = () => {
grecaptcha.render('g-recaptcha', {
'sitekey': '******',
'size': 'compact',
'data-callback': 'ok-you-can-submit-the-form',
'data-expired-callback': 'you-have-to-click-recaptcha-again',
'data-error-callback': 'something-went-wrong-please-try-again'
});
}
$(document).ready(function() {
onloadCallback();
}
我在 Chrome 开发工具中遇到错误:
Uncaught ReferenceError: grecaptcha is not defined
所以我猜这是因为bundle.js 不知道<head> 部分中定义的recaptcha 脚本或其相关变量。
如何在不使用内联脚本范例的情况下实现 google reCaptcha?
编辑
我认为 Google 建议使用 nonce-based approach(在 this SO answer 中也建议)仅在您使用 automatic rendering(只需要 <script src="****"> 标记)时才有效。
如果您像我一样使用explicit rendering,这需要内联定义回调函数,那么我认为nonce 方法行不通。
【问题讨论】:
-
您需要为此使用适当的 npm 构建,通常的 recaptcha CDN 构建不适用于 webpack
标签: javascript jquery recaptcha