Я нашел проблему. Вот как я это исправил:
<script>
var onloadCallback, onerrorCallback;
var promise = new Promise(function(resolve, reject) {
onerrorCallback = function() {
reject();
}
onloadCallback = function() {
var form = document.createElement('form'),
recaptcha = document.createElement('div');
form.method = 'post';
resolve(grecaptcha.render(recaptcha, {
sitekey: 'INVISIBLE RECAPTCHA SITE KEY',
size: 'invisible',
callback: function() {
form.submit()
}
}));
form.appendChild(recaptcha);
document.body.appendChild(form);
}
})
function userClick() {
promise
.then(function(id) {
grecaptcha.execute(id);
})
.catch(function(){alert('Error')});
}
</script>
<script async defer src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=en" onerror="onerrorCallback()"></script>
<p>Please <a href="javascript:userClick()">click here</a> to solve the recaptcha</p>
Проблема была в вызове then (). Из-за того, что grecaptcha не определен, JavaScript остановился и никогда не дошел до вызова catch (). Сообщение об ошибке, напечатанное на консоли, не имело к этому никакого отношения.
Я исправил его, обернув вызов grecaptcha.execute в анонимную функцию.