You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google reCaptcha v2 工作不稳定问题排查求助

Google reCAPTCHA 表单提交异常排查求助

从未部署过Google reCAPTCHA,目前遇到两个问题:

  • 表单提交时而成功时而失败;
  • 未勾选验证码提交失败后,重新勾选验证码仍无法发送邮件。

附上相关代码及报错信息,请求协助排查:

后台代码

protected static string ReCaptcha_Key = "<key>";
protected static string ReCaptcha_Secret = "<key>";

public bool IsReCaptchValid()
{
    var result = false;
    var captchaResponse = Request.Form["g-recaptcha-response"];
    var secretKey = ReCaptcha_Secret;
    var apiUrl = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
    var requestUri = string.Format(apiUrl, secretKey, captchaResponse);
    var request = (HttpWebRequest)WebRequest.Create(requestUri);

    using (WebResponse response = request.GetResponse())
    {
        using (StreamReader stream = new StreamReader(response.GetResponseStream()))
        {
            JObject jResponse = JObject.Parse(stream.ReadToEnd());
            var isSuccess = jResponse.Value<bool>("success");
            result = (isSuccess) ? true : false;
        }
    }
    return result;
}

protected void btnSend_Click(object sender, EventArgs e)
{
    string Name = txtName.Text;
    string EmailAddress = txtEmail.Text;
    string phone = "Number not supplied";
    if(txtPhone.Text != "")
    {
        phone = txtPhone.Text;
    }
    
    string SendAddress = @"<email address>";
    string Subject = "Message from " + Name + " Top Tree Fellas Website";
    string Message = Regex.Replace(txtMsg.Text, @"\r\n?|\n", "<br />");
    if (String.IsNullOrEmpty(Name) || String.IsNullOrEmpty(EmailAddress) || String.IsNullOrEmpty(Message) || !(IsReCaptchValid()))
    {
        lblError.Text = "Please ensure all required fields are filled in.";
    }
    else
    {
        try
        {
            MailMessage msg = new MailMessage();
            msg.To.Add(new MailAddress(@"<email address>"));
            msg.Subject = Subject;
            msg.From = new MailAddress(SendAddress);
            msg.IsBodyHtml = true;
            msg.Body = "<p><strong>Contact Name:</strong> " + Name + "<br />";
            msg.Body += "<strong>Email Address:</strong> " + EmailAddress + "<br />";
            msg.Body += "<strong>Phone:</strong> " + phone + "<br />";
            msg.Body += "<strong>Message:</strong><br />" + Message + "</p>";

            msg.ReplyToList.Add(new MailAddress(EmailAddress));


            SmtpClient smtpClnt = new SmtpClient("smtp.ionos.co.uk");
            smtpClnt.UseDefaultCredentials = false;
            smtpClnt.Port = 587;
            smtpClnt.Credentials = new NetworkCredential(@"<email address>", "<password>");
            smtpClnt.EnableSsl = true;


            smtpClnt.Send(msg);


            lblError.ForeColor = System.Drawing.Color.Green;
            txtName.Text = "";
            txtEmail.Text = "";
            txtMsg.Text = "";
            txtPhone.Text = "";
            Response.Write("<script>alert('Message sent');</script>");
        }

        catch (Exception er)
        {
            string er1 = er.Message + "<br />" + er.InnerException;
            lblError.Text = er1;
            Response.Write("<script>alert('Something went wrong. Please try again later or call us on: 0<phone number>');</script>");
        }
    }
}

页面标记

<script src='https://www.google.com/recaptcha/api.js'></script>  
<div class="g-recaptcha" data-type="image" data-sitekey="6LfDHwcpAAAAAL71bUOZ4291MqxqDyTfvGbzOMcg"></div>
<asp:Button ID="btnSend" runat="server" ValidationGroup="vldContact" Text="Send your message" CssClass="btn btn-danger" OnClick="btnSend_Click" />

Web.config配置

<system.net>
    <defaultProxy>
        <proxy usesystemdefault = "false" bypassonlocal="false" proxyaddress="http://ntproxyus.lxa.perfora.net:3128"/>
    </defaultProxy>
</system.net>

报错信息

Failure sending mail.
System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.TlsStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.Mail.SmtpPooledStream.Dispose(Boolean disposing) at System.IO.Stream.Close() at System.IO.Stream.Dispose() at System.Net.ConnectionPool.Destroy(PooledStream pooledStream) at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse) at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpClient.GetConnection() at System.Net.Mail.SmtpClient.Send(MailMessage message)

排查方向及解决方案

1. reCAPTCHA验证逻辑问题

  • 验证码一次性使用问题:Google reCAPTCHA的g-recaptcha-response是一次性的,提交后立即失效。第一次未勾选提交失败后,页面回发时reCAPTCHA控件不会自动重置,导致第二次勾选后可能仍使用旧的无效响应值。
    解决:在后台返回错误提示后,强制重置reCAPTCHA:
    // 在lblError.Text = "Please ensure all required fields are filled in.";后添加
    ScriptManager.RegisterStartupScript(this, GetType(), "resetCaptcha", "grecaptcha.reset();", true);
    
  • 验证请求异常处理:当前IsReCaptchValid()方法未处理网络异常,若请求Google验证接口失败会直接抛出异常,导致表单进入错误分支。
    解决:给验证方法添加异常捕获:
    public bool IsReCaptchValid()
    {
        try
        {
            var captchaResponse = Request.Form["g-recaptcha-response"];
            if(string.IsNullOrEmpty(captchaResponse)) return false;
            
            var secretKey = ReCaptcha_Secret;
            var apiUrl = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
            var requestUri = string.Format(apiUrl, secretKey, captchaResponse);
            var request = (HttpWebRequest)WebRequest.Create(requestUri);
    
            using (WebResponse response = request.GetResponse())
            using (StreamReader stream = new StreamReader(response.GetResponseStream()))
            {
                JObject jResponse = JObject.Parse(stream.ReadToEnd());
                return jResponse.Value<bool>("success");
            }
        }
        catch(Exception ex)
        {
            // 可添加日志记录逻辑
            return false;
        }
    }
    

2. SMTP邮件发送异常(报错核心原因)

报错显示连接被主机端软件中止,结合代理配置,重点排查以下几点:

  • 代理配置冲突:当前代理可能无法正确连接IONOS的SMTP服务器,尝试绕过代理访问SMTP:
    修改Web.config的defaultProxy节点:
    <defaultProxy>
        <proxy usesystemdefault = "false" bypassonlocal="false" proxyaddress="http://ntproxyus.lxa.perfora.net:3128"/>
        <bypasslist>
            <add address="^https?://smtp\.ionos\.co\.uk$"/>
        </bypasslist>
    </defaultProxy>
    
  • SSL/TLS版本问题:.NET默认TLS版本可能不被IONOS支持,强制使用TLS 1.2:
    在smtpClnt.Send(msg)前添加:
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    
  • SMTP连接池问题:连接中止可能是连接池复用异常,禁用连接池:
    smtpClnt.ServicePoint.ConnectionLeaseTimeout = 0;
    smtpClnt.ServicePoint.MaxIdleTime = 0;
    

3. 表单回发状态问题

确保ASP.NET回发后,reCAPTCHA控件能重新生成有效的响应值,避免旧值残留导致验证失败。


内容的提问来源于stack exchange,提问作者M_Griffiths

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:25:58