Penjelasan Mendalam

Mekanisme Callback reCAPTCHA v2: Cara Kerja dan Cara Memicunya

Saat pengguna menyelesaikan tantangan reCAPTCHA v2, Google memanggil fungsi callback JavaScript yang ditentukan oleh situs. Callback ini biasanya mengaktifkan tombol kirim, memvalidasi formulir, atau mengirimkan permintaan AJAX. Setelah memasukkan token yang telah diselesaikan dari CaptchaAI, Anda perlu memicu callback yang sama — jika tidak, formulir tidak akan mengenali bahwa CAPTCHA telah diselesaikan.


Cara kerja callback

Situs ini mendefinisikan callback di widget reCAPTCHA:

<div class="g-recaptcha"
     data-sitekey="6Le-SITEKEY"
     data-callback="onCaptchaSuccess"
     data-expired-callback="onCaptchaExpired">
</div>

<script>
function onCaptchaSuccess(token) {
  document.getElementById('submit-btn').disabled = false;
  document.getElementById('captcha-token').value = token;
}
</script>

Saat pengguna memecahkan CAPTCHA, JavaScript Google memanggil onCaptchaSuccess(token). Fungsi tersebut menerima string token sebagai satu-satunya argumennya.


Menemukan fungsi callback

Metode 1: Periksa atribut data-callback

// In browser console
const widget = document.querySelector('.g-recaptcha');
const callbackName = widget?.getAttribute('data-callback');
console.log('Callback:', callbackName);

Metode 2: Periksa internal grecaptcha

Beberapa situs menggunakan grecaptcha.render() dengan opsi callback alih-alih atribut data-callback:

// Search page source for grecaptcha.render
document.querySelectorAll('script:not([src])').forEach(s => {
  if (s.textContent.includes('grecaptcha.render')) {
    console.log(s.textContent.match(/callback\s*:\s*(\w+)/)?.[1]);
  }
});

Metode 3: Cegat pendaftaran callback

Jalankan ini di DevTools sebelum halaman dimuat (Sumber Cuplikan →):

const origRender = grecaptcha.render;
grecaptcha.render = function(container, params) {
  console.log('Render callback:', params.callback);
  console.log('Expired callback:', params['expired-callback']);
  return origRender.apply(this, arguments);
};

Memicu callback setelah pengaturan token

Piton (Selenium)

import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_API_KEY"
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")

# Extract sitekey and callback
sitekey = driver.find_element(
    By.CSS_SELECTOR, ".g-recaptcha"
).get_attribute("data-sitekey")

callback = driver.find_element(
    By.CSS_SELECTOR, ".g-recaptcha"
).get_attribute("data-callback")

# Solve with CaptchaAI
resp = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": driver.current_url,
    "json": "1",
}).json()
task_id = resp["request"]

token = None
for _ in range(24):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": "1"
    }).json()
    if result["status"] == 1:
        token = result["request"]
        break

# Inject token into textarea
driver.execute_script("""
    document.querySelector('textarea[name="g-recaptcha-response"]').value = arguments[0];
""", token)

# Trigger the callback
if callback:
    driver.execute_script(f"window['{callback}'](arguments[0]);", token)
    print(f"Triggered callback: {callback}")
else:
    # Fallback: try ___grecaptcha_cfg
    driver.execute_script("""
        try {
            var widgetId = Object.keys(___grecaptcha_cfg.clients)[0];
            var callback = ___grecaptcha_cfg.clients[widgetId].aa.l.callback;
            if (typeof callback === 'function') callback(arguments[0]);
        } catch(e) {}
    """, token)
    print("Triggered callback via ___grecaptcha_cfg")

JavaScript (Puppeteer)

const puppeteer = require('puppeteer');

// After solving and getting the token...
await page.evaluate((token, callbackName) => {
  // Set textarea value
  const textarea = document.querySelector(
    'textarea[name="g-recaptcha-response"]'
  );
  textarea.value = token;
  textarea.style.display = 'block'; // sometimes hidden

  // Trigger callback
  if (callbackName && typeof window[callbackName] === 'function') {
    window[callbackName](token);
    console.log(`Called ${callbackName}()`);
  } else {
    // Fallback: search grecaptcha config
    try {
      const clients = ___grecaptcha_cfg.clients;
      const widgetId = Object.keys(clients)[0];
      const cb = clients[widgetId]?.aa?.l?.callback;
      if (typeof cb === 'function') cb(token);
    } catch (e) {}
  }
}, token, callbackName);

Situs tanpa callback data

Beberapa situs tidak menggunakan callback. Sebaliknya, mereka memeriksa grecaptcha.getResponse() saat formulir diserahkan. Untuk situs berikut, ganti fungsinya:

driver.execute_script("""
    const token = arguments[0];
    document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
    // Override getResponse to return the token
    if (typeof grecaptcha !== 'undefined') {
        grecaptcha.getResponse = function() { return token; };
    }
""", token)

# Then submit the form normally
driver.find_element(By.CSS_SELECTOR, "form").submit()

Callback sudah habis masa berlakunya

Beberapa situs menetapkan data-expired-callback untuk menonaktifkan tombol kirim ketika token expiry. Jika token Anda hampir habis masa berlakunya, callback ini mungkin diaktifkan dan mengunci kembali formulir. Selesaikan mendekati waktu penyerahan untuk menghindari hal ini.

// Check for expired callback
const expiredCallback = document.querySelector('.g-recaptcha')
  ?.getAttribute('data-expired-callback');
console.log('Expired callback:', expiredCallback);

Pemecahan Masalah

Masalah Penyebab Solusi
Formulir masih dinonaktifkan setelah injeksi Callback tidak terpicu Temukan dan panggil fungsi callback
ReferenceError: function not defined Callback didefinisikan dalam penutupan Gunakan cadangan ___grecaptcha_cfg
Token disuntikkan tetapi AJAX tidak terkirim Callback memicu AJAX, bukan pengiriman formulir Periksa apa fungsi callback
Token diterima tetapi halaman menunjukkan kesalahan Token expiry sebelum callback Selesaikan lebih dekat dengan waktu penyerahan

Pertanyaan Umum

Bagaimana jika tidak ada callback sama sekali?

Beberapa situs hanya memeriksa token di sisi server saat formulir dikirimkan. Dalam hal ini, menetapkan nilai textarea g-recaptcha-response dan mengirimkan formulir sudah cukup.

Bisakah nama fungsi callback berubah di antara pemuatan halaman?

Ya, di beberapa situs. Selalu ekstrak nama callback secara dinamis dari DOM daripada melakukan hardcoding.

Apakah reCAPTCHA v3 menggunakan mekanisme callback yang sama?

Tidak. reCAPTCHA v3 menggunakan grecaptcha.execute() yang mengembalikan Janji. Tidak ada widget atau atribut data-callback yang terlihat.


Selesaikan reCAPTCHA v2 dengan penanganan callback yang tepat menggunakan CaptchaAI

Dapatkan kunci API Anda dicaptchaai.com.


Panduan terkait

  • reCAPTCHA v2 Invisible: Deteksi Pemicu
  • Mengekstrak Parameter reCAPTCHA dari Sumber Halaman
  • Menangani Beberapa CAPTCHA dalam Satu Halaman
Komentar dinonaktifkan untuk artikel ini.