Recaptcha disappears during PostBack

此生再无相见时 提交于 2019-12-05 05:22:59

Forget the ScriptManager. All you need is this script in the page. Change accordingly for your identifiers:

<script type="text/javascript">
// RECAPTURE CODE FOR RELOADING AFTER INCORRECT ENTRY
if (typeof Sys != 'undefined') {
    var requestManager = Sys.WebForms.PageRequestManager.getInstance();
    requestManager.add_endRequest(function(sender, args) {

        $('<div id="recaptcha_widget_div"/>').appendTo('#recaptcha_widget_div2');

        if (typeof Recaptcha != 'undefined') {                                
            Recaptcha.create(recaptcha_key, "recaptcha_widget_div",
            {
                theme: "red",
                callback: Recaptcha.focus_response_field
            });
        }
    });
}

The accepted solution did not work for me. Here is the answer that I have tried and is working:

ASP.Net, disappearing Recaptcha, UpdatePanels and Partial PostBacks: Fixed once and for all

Basically it involves creating a hidden div and using jquery to re-render the html. Also the blog post gives a nice little breakdown of the typical solutions (e.g., using RegisterClientScriptBlock with a simple reload) and why they fail.

<div runat="server" id="pbTarget" visible="false"></div>  
<recaptcha:RecaptchaControl ID="recaptcha" runat="server" Theme="clean" />  

code behind:

protected void btnSubmit_Click(object sender, EventArgs e)  
{  
  recaptcha.Validate();  
  if (!Page.IsValid || !recaptcha.IsValid)  
  {  
    pbTarget.Visible = true;  
    ScriptManager.RegisterClientScriptBlock(  
      recaptcha,  
      recaptcha.GetType(),  
      "recaptcha",  
      "Recaptcha._init_options(RecaptchaOptions);"  
      + "if ( RecaptchaOptions && \"custom\" == RecaptchaOptions.theme )"  
      + "{"  
      + "  if ( RecaptchaOptions.custom_theme_widget )"  
      + "  {"  
      + "    Recaptcha.widget = Recaptcha.$(RecaptchaOptions.custom_theme_widget);"  
      + "    Recaptcha.challenge_callback();"  
      + "  }"  
      + "} else {"  
      + "  if ( Recaptcha.widget == null || !document.getElementById(\"recaptcha_widget_div\") )"  
      + "  {"  
      + "    jQuery(\"#" + pbTarget.ClientID + "\").html('<div id=\"recaptcha_widget_div\" style=\"display:none\"></div>');"  
      + "    Recaptcha.widget = Recaptcha.$(\"recaptcha_widget_div\");"  
      + "  }"  
      + "  Recaptcha.reload();"  
      + "  Recaptcha.challenge_callback();"  
      + "}",  
      true  
    );  

    return;  
  }  
  else  
  {  
    //normal page processing here...  

If you are using Recaptcha 2.0 this is your Javascript

 <script type="text/javascript">
    function CaptchaReload() {
          Recaptcha.create("yourpublicKey", 'yourRecaptchadiv', {
          theme: 'white',
          callback: grecaptcha.reset()

        });
      }

This is your recaptcha Div

<div class="g-recaptcha" data-sitekey="yourPublicKey"></div>

Then at end of postback event call the Javascript

 protected void txtEmail_TextChanged(object sender, EventArgs e)
{
    if (txtEmail.Text != string.Empty)
    {
        ValidateEmail();
        ScriptManager.RegisterStartupScript(this, this.GetType(), "CaptchaReload", "$.getScript(\"https://www.google.com/recaptcha/api.js\", function () {});", true);
    }
}

Surprisingly, I didn't need to apply the RegisterClientScriptBlock call to make it work. I just use:

UpdateMode="Always"

for the updatepanel and on the server side I call:

updatePanel.Update();

This also prevents the captcha from displaying a new challenge.

My answer is basically the same as "User" (that worked !), but to help anyone using VB. I would have commented there, but I have zippo rep... (hope this isn't too much of an infraction, and that it helps someone out)

I ported the meat of this to VB.NET:

pbTarget.Visible = True
        Dim _sb As New StringBuilder
        With _sb
            .Append("Recaptcha._init_options(RecaptchaOptions);")
            .Append("if ( RecaptchaOptions && ""custom"" == RecaptchaOptions.theme )")
            .Append("{")
            .Append("  if ( RecaptchaOptions.custom_theme_widget )")
            .Append("  {")
            .Append("    Recaptcha.widget = Recaptcha.$(RecaptchaOptions.custom_theme_widget);")
            .Append("    Recaptcha.challenge_callback();")
            .Append("  }")
            .Append("} else {")
            .Append("  if ( Recaptcha.widget == null || !document.getElementById(""recaptcha_widget_div"") )")
            .Append("  {")
            .Append("    jQuery(""#")
            .Append(pbTarget.ClientID)
            .Append(""").html('<div id=""recaptcha_widget_div"" style=""display:none""></div>');")
            .Append("    Recaptcha.widget = Recaptcha.$(""recaptcha_widget_div"");")
            .Append("  }")
            .Append("  Recaptcha.reload();")
            .Append("  Recaptcha.challenge_callback();")
            .Append("}")
        End With
        ScriptManager.RegisterClientScriptBlock(recaptcha, recaptcha.[GetType](), "recaptcha", _sb.ToString, True)

I was able to make it work using version 2.1.0.0 of the reCAPTCHA library for .NET with webforms, script manager and inside an update panel.

First, in the .aspx page outside of the update panel I'm loading the Google reCAPTCHA library:

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" 
            async defer></script>

Second, in the .aspx page inside the update panel I added a div that will work as the target panel to load the reCAPTCHA:

<div runat="server" id="pbTarget" visible="false"></div>
<cc1:Recaptcha ID="recaptcha" runat="server" Theme="Clean" />

Third, in the code behind at the end of my postback event I registered a startup script to render the reCAPTCHA in my target panel

Private Sub cmdSubmit_Click(sender As Object, e As EventArgs) Handles cmdSubmit.Click
    pbTarget.Visible = True
    ScriptManager.RegisterStartupScript(
        UpdatePanel1,
        UpdatePanel1.GetType(),
        "loadCaptcha",
        "grecaptcha.render('" & pbTarget.ClientID & "', {'sitekey': 'YourKey' });",
End Sub

You need to reload reCaptcha control with javascript, try this:

protected void Button1_Click(object sender, EventArgs e)
{
     btnrecaptcha.Validate();
     if(IsValid && updRecaptcha.IsValid}
     {
          //Some logic here
     }
     ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "CaptchaReload", "Recaptcha.reload();", true);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!