2011-08-09 39 views
1

我正在驗證使用AJAX的CAPTCHA輸入。我意識到我無法從AJAX調用中的成功處理函數返回值,所以我創建了一個全局變量,以便成功處理函數和驗證函數可以與其他人交流。但它不是以最令人迷惑的方式工作的。首先,代碼:我可以在事件處理程序中更改全局變量嗎?

jQuery('#contact').submit(function(event) { 
     if (validate_form()) 
     { 
      submit_form(event); 
     } 
     else 
     { 
      return false; 
     } 
    }); 

var valid = true; 

function validate_form() 
{ 
    valid = true; 

    // test form stuff here 
    // if something goes wrong valid will be set to false 

    if (!valid) 
    { 
     alert("form is not valid, refreshing captcha"); 
     // refresh form 
     // .... 
    } 
    else 
    { 
     alert("form is valid, checking captcha"); 
     check_recaptcha(); 
    } 

    alert("finally, form is:" + valid); 
    return valid; 
} 

function check_recaptcha() 
{ 
    alert("checking captcha now"); 
    // take only recaptcha values from form 
    var recaptcha_vals = jQuery(':input[name^="recaptcha"]').serialize(); 
    jQuery.post('recaptcha.php', recaptcha_vals, function(data) { 
     alert("recaptcha post has succeeded!"); 
     if (data == '1\n' /*success!*/) 
     { 
      alert("recaptcha is correct!"); 
      jQuery('#recaptcha_error').empty(); 
     } 
     else 
     { 
      alert("recaptcha is incorrect!"); 
      show_recaptcha(); 
      jQuery('#recaptcha_error').html("<p class=\"error\">CAPTCHA was incorrect, please try again.</p>"); 
      valid = false; 
     } 
    }); 
} 

我測試此代碼沒有在CAPTCHA輸入字段(一個顯然是不正確的值)。根據警報,代碼的每個部分都按預期執行,除了valid仍然是true,執行check_recaptcha()後,即使我知道遵循了「不正確」的分支。因此,問題1是:爲什麼事件處理程序不能將valid設置爲false

這是它變得奇怪的地方。在上述情況下,即使validate_form()返回true(根據警報),表單也不會提交。但是,當我註釋掉所有警報並使用完全相同的輸入再次嘗試時,則會提交表單。所以問題2是:這是怎麼回事? ##1雖然更重要。

+0

如何在jQuery調用之前嘗試將'var valid = true;'放在一起? – Nayuki

+0

@nayuki只會重置'有效'作爲本地回調的範圍...不是我所需要的。 – Xaq

回答

2

異步回調的要點是,jQuery.post()將立即返回,而無需等待來自recaptcha服務的回覆。因此,當你「終於」發出警報時,recapthcha轉換是仍然在,並且當它完成時你的回調將被調用。然後,當您的警報等待您單擊確定時,將會收到回覆答覆,並且您的回調會運行。如果您註釋掉提醒,您的提交處理程序將在之前完成回調有機會將有效設置爲false。

這就是爲什麼您需要首先提供回調,而不是僅僅讀取返回值。

:您知道檢查客戶端上的驗證碼是毫無意義的,除非您稍後在服務器端重複檢查,對嗎? (即使你在服務器上重複它也是毫無意義的,客戶端驗證的重點是在不等待網絡往返服務器的情況下,爲用戶提供即時反饋,如果你等待提交,直到完成往返檢查驗證碼,除了成功案例中的響應時間增加了一倍之外,你完成了任何事情。唯一可以考慮的例外是,如果你的表單包含非常大量的數據,需要花費大量時間進行傳輸)。

+0

這很清楚,謝謝!是的,我要發佈的php腳本具有所有的代碼來檢查recaptcha服務的答案,並返回一些表明結果的文本。 – Xaq

+0

那麼爲什麼在提交前單獨檢查?它只是浪費時間。 –

+0

爲了避免重新加載整個表單,它的某些狀態可能已經被jQuery改變了,如果表單被重新加載,這個狀態會丟失。根據用戶在下拉菜單中的選擇顯示或隱藏字段。讓所有內容與所顯示內容保持同步的機制非常複雜,而且我不想讓HTML和PHP的負擔跟蹤每個用戶更改時的所有內容。另外,這是我第一次嘗試jQuery和AJAX,所以很可能我不知道自己在做什麼。 – Xaq

0

我在這裏找到我的答案:Javascript Local vs Global。然而,我反對這個答案的建議,並且確實將我的請求設置爲同步的,這在我的應用程序的上下文中運行良好。

+0

Henning的回答解釋了我爲什麼遇到這個問題,但是我從這個問題中得到了「該怎麼做」。 – Xaq

相關問題