Blazor SSR中Google ReCAPTCHA Enterprise切换页面后消失问题排查
问题原因
Blazor SSR采用客户端导航时仅局部更新DOM,不会重新加载整个页面。初始加载时,Google ReCAPTCHA Enterprise的enterprise.js脚本会扫描页面中带有g-recaptcha类的容器并渲染验证框;但当切换页面后返回表单页时,新的g-recaptcha容器被添加到DOM后,脚本不会自动重新扫描并初始化这些新元素,导致验证框消失。
解决方案
1. 封装可自动初始化的ReCAPTCHA组件
创建独立组件,利用Blazor的生命周期方法手动触发ReCAPTCHA初始化,确保每次组件渲染(包括页面切换返回时)都能生成验证框:
@inject IJSRuntime JSRuntime @implements IAsyncDisposable <div @ref="recaptchaContainer"></div> @code { private ElementReference recaptchaContainer; private int? _widgetId; [Parameter, Required] public string SiteKey { get; set; } [Parameter] public string Action { get; set; } = "submit"; protected override async Task OnAfterRenderAsync(bool firstRender) { // 每次渲染完成后初始化,覆盖页面切换场景 _widgetId = await JSRuntime.InvokeAsync<int>( "grecaptcha.enterprise.render", recaptchaContainer, new { sitekey = SiteKey, action = Action } ); } public async ValueTask DisposeAsync() { // 组件销毁时清理实例,避免内存泄漏 if (_widgetId.HasValue) { await JSRuntime.InvokeVoidAsync("grecaptcha.enterprise.destroy", _widgetId.Value); } } }
2. 全局引入ReCAPTCHA脚本
将enterprise.js脚本放在应用根布局(如_Layout.cshtml)的<body>末尾,确保脚本在整个应用生命周期内都能被访问:
<script src="https://www.google.com/recaptcha/enterprise.js" async defer></script>
3. 在表单组件中使用自定义组件
替换原有的g-recaptcha容器,改用封装好的组件:
<EditForm Model="@EmailModel" OnValidSubmit="@HandleSubmit"> <!-- 其他表单字段 --> <RecaptchaEnterprise SiteKey="你的Google站点密钥" Action="email_form_submit" /> <button type="submit">发送邮件</button> </EditForm>
4. 获取验证响应(可选)
如果需要在表单提交时获取ReCAPTCHA的验证令牌,可在组件中添加方法:
// 在RecaptchaEnterprise组件中添加 public async Task<string?> GetResponseAsync() { if (_widgetId.HasValue) { return await JSRuntime.InvokeAsync<string>( "grecaptcha.enterprise.getResponse", _widgetId.Value ); } return null; }
然后在表单提交时调用:
private async Task HandleSubmit() { var recaptchaResponse = await RecaptchaComponent.GetResponseAsync(); if (string.IsNullOrEmpty(recaptchaResponse)) { // 处理未完成验证的情况 return; } // 提交表单和验证令牌到后端 }
内容的提问来源于stack exchange,提问作者Pitasoft
相关产品推荐
相关产品推荐

