如何让ASP.NET Core的reCAPTCHA组件加载本地recaptcha__en.js而非外部资源
可行解决方案
以下三个方案按实施成本从低到高排序,你可以根据你使用的包版本选择适配的方案:
方案1:通过服务配置直接覆写脚本地址(优先推荐)
目前新版本的AspNetCore.ReCaptcha包已经内置了脚本地址配置项,你只需要在服务注册时修改对应参数即可:
- 提前下载好
recaptcha__en.js文件,放到项目wwwroot/js目录下,确保你的项目已经开启静态资源中间件 - 修改
Program.cs中的ReCaptcha服务注册代码:
builder.Services.AddRecaptcha(options => { options.SiteKey = "你的ReCaptcha站点密钥"; options.SecretKey = "你的ReCaptcha服务端密钥"; // 此处替换为你本地js文件的访问路径 options.ScriptUrl = "/js/recaptcha__en.js"; });
该配置会直接覆盖组件默认的谷歌CDN脚本地址,不会再发起外部资源请求。
方案2:响应内容替换(适配无ScriptUrl配置的旧版本包)
如果你使用的是旧版本包,没有暴露ScriptUrl配置项,可以通过自定义中间件拦截HTML响应,替换默认的外部脚本地址:
- 同样先把下载好的
recaptcha__en.js放到wwwroot/js目录下 - 新增自定义中间件代码:
public class RecaptchaScriptReplaceMiddleware { private readonly RequestDelegate _next; public RecaptchaScriptReplaceMiddleware(RequestDelegate next) => _next = next; public async Task InvokeAsync(HttpContext context) { // 仅处理HTML类型响应 if (context.Response.ContentType?.Contains("text/html") == true) { var originalBody = context.Response.Body; using var tempStream = new MemoryStream(); context.Response.Body = tempStream; await _next(context); tempStream.Seek(0, SeekOrigin.Begin); var htmlContent = await new StreamReader(tempStream).ReadToEndAsync(); // 将默认的谷歌脚本地址替换为本地地址,字符串匹配请和你实际看到的外部地址保持一致 htmlContent = htmlContent.Replace("https://www.google.com/recaptcha/api.js", "/js/recaptcha__en.js"); context.Response.Body = originalBody; await context.Response.WriteAsync(htmlContent); return; } await _next(context); } }
- 在
Program.cs中注册中间件,注意注册顺序要在静态资源中间件之后、路由中间件之前:
app.UseStaticFiles(); // 注册脚本替换中间件 app.UseMiddleware<RecaptchaScriptReplaceMiddleware>(); app.UseRouting();
方案3:手动渲染ReCaptcha组件
完全弃用包自带的TagHelper标签渲染逻辑,自行编写前端渲染代码,服务端验证逻辑保持不变:
- 页面中直接引入本地js文件,手动编写reCAPTCHA容器:
<!-- 引入本地脚本 --> <script src="~/js/recaptcha__en.js"></script> <!-- 手动写reCAPTCHA容器,替换为你自己的站点密钥 --> <div class="g-recaptcha" data-sitekey="你的站点密钥"></div>
- 服务端验证依然可以使用原包的
[ValidateReCaptcha]特性,或者注入IReCaptchaService手动调用验证方法,完全不影响原有验证逻辑。
注意:采用本地加载方案后,如果后续需要升级reCAPTCHA的JS版本,需要手动下载新的js文件替换本地资源。
内容的提问来源于stack exchange,提问作者SamyCode
相关产品推荐
相关产品推荐

