laravel-recaptcha安装后不显示验证码需手动添加@captcha及renderjs(v2)或grecaptcha.execute(v3),并确保js加载时机、csp策略、密钥配置、版本一致性和action名称匹配。

laravel-recaptcha 安装后不显示验证码
默认情况下,laravel-recaptcha 只注入 JS 脚本,但不会自动渲染控件——你得手动在表单里加 @captcha 或 {!! NoCaptcha::renderJs() !!}(v2)或 <div class="g-recaptcha" data-sitekey="..."></div>(v3)。不写这行,页面干干净净,啥也不出。
常见错误现象:reCAPTCHA couldn't find user-provided function: onSubmit 或控制台报 grecaptcha is not defined,基本都是 JS 加载时机或位置不对。
- 确保
@captcha放在<form></form>内、提交按钮之前 - v2 需要同时调用
@captcha和{!! NoCaptcha::renderJs() !!}(后者建议放页面底部或末尾) - v3 不需要 DOM 元素,但必须在提交前调用
grecaptcha.execute('xxx', {action: 'login'})并把 token 塞进隐藏字段 - 检查是否启用了 CSP(Content-Security-Policy),会拦截 Google 的 JS;临时关闭测试可快速定位
验证失败时 validate() 报 Invalid captcha 但没提示
Laravel 默认把 recaptcha 字段当普通字段校验,但错误消息不会自动绑定到视图的 $errors,除非你显式加规则或重写 message。
使用场景:登录/注册表单提交后跳回,用户看不到任何提示,只发现表单没提交成功。
- 在 Request 类或控制器中,用
'g-recaptcha-response' => 'required|recaptcha',而不是'recaptcha' => ... - 确保配置项
config/recaptcha.php中的version和你前端用的 v2/v3 一致,否则服务端校验直接失败 - 如果用自定义验证规则,别漏掉
use Illuminate\Support\Facades\Validator;,且规则名必须是recaptcha(小写) - v3 的 score 判断需手动加逻辑,比如
if ($score withErrors(['g-recaptcha-response' => '验证未通过']);
本地开发环境无法通过验证
Google reCAPTCHA 对域名校验严格:localhost 不在白名单里,但可以走特殊处理。
参数差异:v2 支持 localhost,v3 默认不支持(需在 Google Cloud Console 显式添加 http://localhost 和 http://127.0.0.1)。
- 去 Google reCAPTCHA Admin Console,为 localhost 创建密钥对(选择 reCAPTCHA v2 “我不可见的 reCAPTCHA” 或 v3)
- 不要复用生产环境的 key,否则本地调试时可能触发 rate limit 或被拒绝
- 确认
.env中RECAPTCHA_SITE_KEY和RECAPTCHA_SECRET_KEY已更新,且没有空格或换行 - 清空 config 缓存:
php artisan config:clear,否则改了 .env 也无效
切换 v2 和 v3 时路由中间件失效
v2 是表单字段校验,v3 是后台评分制,两者验证逻辑完全不同,不能共用同一套中间件或 Request 规则。
性能 / 兼容性影响:v3 无用户交互,适合埋点式验证,但 score 解析需额外判断;v2 有明确交互,兼容性更好,但体验略重。
- v2 推荐用
RecaptchaV2中间件(如app/Http/Middleware/RecaptchaV2.php),检查g-recaptcha-response是否存在且有效 - v3 必须在控制器里调用
ReCaptcha::verify($request->token, $action),并传入对应 action(如'login'),否则返回 score 但无法匹配策略 - 别在同一个表单混用 v2 和 v3 的 JS 加载脚本,会冲突;删干净旧的
https://www.google.com/recaptcha/api.js引用 - v3 的 token 有效期只有 2 分钟,提交延迟过长会导致
invalid-input-response
最常被忽略的是 action 名称一致性:前端 grecaptcha.execute('xxx', {action: 'register'}) 和后端 ReCaptcha::verify($token, 'register') 必须完全一样,大小写敏感,拼错一个字母就白忙活。










