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