Динамическое обновление reCAPTCHA v3 в Laravel

Когда требуется добавить какой-то функционал на сайт, первое что обычно делается это устанавливается какой-то пакет который позволяет полностью или частично решить задачу, чтобы не изобретать того что уже сделано. Для интеграции Google Captcha есть несколько готовых пакетов для Laravel. Я не изучал их всех и не сравнивал, а просто установил один из самых популярных пакетов, а именно josiasmontag/laravel-recaptchav3.

Базовая настройка капчи не вызывает каких либо вопросов, и я не буду тут копировать документацию. Но после установки сразу же возник вопрос, а как же обновить эту капчу без перезагрузки страницы, ведь именно в таком режиме работает большое количество форм на сайтах. В расширении такой функционал отсутствует.

Дальнейший поиск решения привел к тому что надо вызвать некоторый код на JS который перерисует капчу. По сути это почти тот же самый код, который запускается для её первичной инициализации. Нюанс в том что для того чтобы код отработал помимо ключа капчи нужно передать ID поля ввода который нужно привязать к капче. Звучит просто тривиально, но мы используем готовый пакет который генерирует этот ID случайным образом, и после этого никуда его не записывает. В функции генерации поля капчи не хватает всего одного параметра для передачи туда желаемого ID.

Можно было бы расширить пакет. Можно, но зачем? Раз уж форма обрабатывается через JavaScript то почему бы не использовать его. Я использую в большинстве проектов jQuery, поэтому решение будет на нем.

<script type="text/javascript">
function refresh_recaptcha3(action, input_id) {
    grecaptcha.execute('{{ env('RECAPTCHAV3_SITEKEY') }}', {action: action}).then(function(token) {
        document.getElementById(input_id).value = token;
    });
}
</script>

И тогда в обработчике формы в нужном месте можно будет вызывать:

refresh_recaptcha3('feedback', $('#feedback-form').find('[name="g-recaptcha-response"]').attr('id'));

В своем проекте я поместил функцию перерисовки в компонент, который целиком выводит поле для ввода капчи и регистрирует нужный скрипт, но т.к. во фреймворке добавление скриптов и стилей жестко не типизировано, он может подойти в таком виде не всем, но тем не менее я опубликую и его код.

{{-- resources/views/components/recaptcha3.blade.php --}}
@props(['action' => null])
@once
{!! RecaptchaV3::initJs() !!}
@push('scripts')
<script type="text/javascript">        
function refresh_recaptcha3(action, input_id)
{
    grecaptcha.execute('{{ env('RECAPTCHAV3_SITEKEY') }}', {action: action}).then(function(token) {
        document.getElementById(input_id).value = token;
    });
}
</script>
@endpush
@endonce
{!! RecaptchaV3::field($action) !!}

Тогда первичный рендеринг капчи можно делать через него.

<x-recaptcha3 action="feedback" />

Как видно из статьи, в динамической перезагрузки капчи нет ничего сложного, но я потратил определенное количество времени чтобы найти хорошее и правильное решение, и стал что-то придумывать сам после того как убедился что его просто нет.

10.02.2026

Комментарии

  • Нет комментариев.

Добавить комментарий

Сайт не собирает персональных данных через форму добавления комментариев.