لرمز Cloudflare Turnstile عمر افتراضي قصير: نحو 300 ثانية (خمس دقائق) من لحظة توليده. إذا انقضى وقت أطول من ذلك بين استلامك للرمز وإرساله إلى الموقع، تُرفض الاستجابة ويعود التحدي من جديد. غالبًا ما يظهر هذا الخلل فجأة — كل شيء يعمل أثناء الاختبار، ثم يبدأ الإنتاج بالفشل بلا سبب ظاهر. الحل ليس في تمديد عمر الرمز، فهذا غير ممكن، بل في معرفة اللحظة التي تبدأ فيها الساعة بالضبط، وإدارة الفجوة الزمنية بين الحل والإرسال بذكاء.
كم يدوم رمز Cloudflare Turnstile قبل انتهاء صلاحيته؟
تنتهي صلاحية رمز Turnstile بعد نحو 300 ثانية (5 دقائق) من إنشائه. هذه المهلة أكثر سخاءً من مهلة reCAPTCHA البالغة نحو 120 ثانية، لكنها لا تُلغي خطر ظروف السباق في سير العمل الذي يمرّ بعدة مراحل قبل الإرسال.
| نوع التحقق | عمر الرمز |
|---|---|
| reCAPTCHA v2/v3 | ~120 ثانية |
| Cloudflare Turnstile | ~300 ثانية |
| hCaptcha | ~120 ثانية |
النقطة الجوهرية: تبدأ الساعة عندما يولّد Cloudflare الرمز — لا عندما يعيده CaptchaAI إليك، ولا عندما يصل إلى شيفرتك. أي تأخير في خط المعالجة يُحسب من هذه المهلة، لا يُضاف إليها.
أين تنشأ ظروف السباق تحديدًا
لنفكّك ما يجري زمنيًا عند إرسال مهمة Turnstile إلى CaptchaAI:
Time 0:00 — You submit a Turnstile task to CaptchaAI
Time 0:15 — CaptchaAI begins solving
Time 0:20 — Token is generated (timer starts here)
Time 0:25 — CaptchaAI returns token to you
Time 0:25+ — Your code processes the token
Time ??? — Your code submits the token to the site
الساعة تعمل منذ اللحظة 0:20، وأمامك حتى الساعة 5:20 تقريبًا لإرسال الرمز. تبدو المهلة مريحة، لكن انظر ما الذي يحدث فعليًا في سير عمل واقعي:
Time 0:20 — Token generated
Time 0:25 — Received by your code
Time 0:30 — Fill form fields
Time 0:35 — Navigate to next page
Time 1:00 — Handle additional dialogs
Time 2:00 — Wait for page load
Time 4:00 — Network latency spike
Time 5:30 — Submit token → EXPIRED
يتضح من هذا المسار أن المهلة تتآكل من ثلاثة مصادر رئيسية:
- خطوات النموذج التي تسبق زر الإرسال النهائي
- زمن تحميل الصفحات وانتظار ظهور العناصر
- تذبذب زمن استجابة الشبكة وقفزات التأخير المفاجئة
سيناريوهات شائعة تستنزف عمر الرمز
تظهر ظروف السباق غالبًا في ثلاثة أنماط من سير العمل، ولكل منها علاج مباشر:
- النماذج التي تمتد عبر عدة صفحات قبل الإرسال
- قوائم المعالجة الدُفعية التي تحل الرموز مسبقًا
- حلقات إعادة المحاولة التي تعيد استخدام الرمز نفسه
النماذج متعددة الخطوات
النماذج التي تتطلب عدة صفحات قبل الإرسال النهائي:
Step 1: Fill personal info → Step 2: Fill address →
Step 3: Solve CAPTCHA → Step 4: Review → Step 5: Submit
إذا ظهر اختبار CAPTCHA في الخطوة 3 وتمّ الإرسال في الخطوة 5، فقد تتجاوز الفجوة بين الحل والإرسال خمس دقائق كاملة، خصوصًا إذا تباطأ المستخدم أو تعثّرت الشبكة.
قوائم المعالجة الدُفعية
حل الرموز مسبقًا واستخدامها لاحقًا يعني أن أقدمها يشيخ وهو ينتظر دوره:
# DON'T: Solve all tokens first, then use them
tokens = []
for url in urls:
tokens.append(solve_turnstile(url)) # Tokens age while waiting
for url, token in zip(urls, tokens):
submit_form(url, token) # Early tokens may be expired
المشكلة هنا مزدوجة:
- الرموز الأولى تشيخ بينما يعالج السكربت بقية الروابط
- كلما طالت القائمة زاد احتمال تجاوز أقدم رمز لحاجز الخمس دقائق
حلقات إعادة المحاولة برموز قديمة
إعادة استخدام الرمز نفسه بعد فشل الإرسال مصيدة شائعة:
token = solve_turnstile(site_key, page_url)
for attempt in range(3):
result = submit_form(page_url, token)
if result.ok:
break
# BUG: Retrying with the same token — it may be expired OR already consumed
كيف تمنع انتهاء صلاحية رمز Cloudflare Turnstile؟
أمامك ثلاث استراتيجيات متكاملة تُبقي الرمز حديثًا حتى لحظة الإرسال:
- حلّ الرمز في اللحظة الأخيرة قبل الإرسال مباشرةً
- تتبّع عمر الرمز والتحقق من صلاحيته برمجيًا قبل استخدامه
- طلب رمز جديد مع كل محاولة إعادة بدل إعادة استخدام القديم
الاستراتيجية 1: احلّ الرمز في اللحظة المناسبة
اطلب الرمز فقط عندما تكون جاهزًا فعلًا للإرسال:
import requests
import time
def solve_turnstile(site_key, page_url):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "turnstile",
"sitekey": site_key,
"pageurl": page_url,
"json": 1
})
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"]
raise TimeoutError("Solve timed out")
# Complete all form steps FIRST
fill_personal_info()
fill_address()
navigate_to_review()
# THEN solve and submit immediately
token = solve_turnstile(site_key, page_url)
submit_form(token) # Submit within seconds of receiving the token
أنجز جميع خطوات النموذج أولًا، ثم احلّ وأرسل مباشرةً. بهذا تبقى الفجوة الزمنية ثوانيَ معدودة بدل دقائق.
الاستراتيجية 2: تتبّع عمر الرمز برمجيًا
غلّف الرمز داخل بنية تعرف متى وُلد، وتحسب المهلة المتبقية قبل استخدامه:
import time
class TimedToken:
def __init__(self, token, created_at=None):
self.token = token
self.created_at = created_at or time.time()
self.max_age = 270 # 4.5 min — safety margin from 5 min limit
@property
def is_valid(self):
return (time.time() - self.created_at) < self.max_age
@property
def remaining_seconds(self):
return max(0, self.max_age - (time.time() - self.created_at))
# Usage
timed_token = TimedToken(solve_turnstile(site_key, page_url))
# Check before using
if timed_token.is_valid:
submit_form(timed_token.token)
else:
# Solve a fresh token
timed_token = TimedToken(solve_turnstile(site_key, page_url))
submit_form(timed_token.token)
اعتماد حد 270 ثانية بدل 300 يمنحك هامش أمان يستوعب تذبذب الشبكة وفروق الساعة.
الاستراتيجية 3: رمز جديد مع كل محاولة (JavaScript)
لا تُعِد إرسال رمز فشل من قبل؛ اطلب رمزًا جديدًا في كل دورة:
async function submitWithFreshToken(siteKey, pageUrl, formData) {
const maxRetries = 3;
for (let attempt = 0; attempt < maxRetries; attempt++) {
// Always solve a fresh token for each attempt
const token = await solveTurnstile(siteKey, pageUrl);
const response = await fetch(pageUrl, {
method: 'POST',
body: JSON.stringify({ ...formData, 'cf-turnstile-response': token }),
headers: { 'Content-Type': 'application/json' }
});
if (response.ok) return await response.json();
console.log(`Attempt ${attempt + 1} failed, solving fresh token...`);
}
throw new Error('All attempts failed');
}
كيف تكتشف رمزًا منتهي الصلاحية؟
نادرًا ما يقول الموقع صراحةً "انتهت صلاحية الرمز". بدلًا من ذلك ابحث عن هذه الإشارات غير المباشرة:
| الإشارة | ما تدل عليه |
|---|---|
| HTTP 403 بعد إرسال الرمز | الرمز غير صالح أو منتهي الصلاحية |
| إعادة توجيه إلى صفحة النموذج من جديد | فشل التحقق من الرمز |
| رسالة "فشل التحقق" العامة | فشل غير محدد قد يكون سببه انتهاء الصلاحية |
| ظهور صفحة التحدي مرة أخرى | رُفض الرمز وأعاد Cloudflare عرض التحدي |
إذا اجتمعت أكثر من إشارة معًا فالأرجح أن السبب هو التوقيت، وترتيب التحقق كالآتي:
- ابدأ بقياس الفجوة الزمنية بين لحظة الحل ولحظة الإرسال
- ثم استبعد اختلاف الجلسة أو الرؤوس بين الاختبار والإنتاج
سجّل التوقيت لتشخيص أدق
لا تُخمّن السبب؛ سجّل عمر الرمز عند لحظة الإرسال لتعرف إن كان التأخير هو المشكلة:
import time
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("turnstile")
token_received_at = time.time()
token = solve_turnstile(site_key, page_url)
logger.info(f"Token received, length: {len(token)}")
# ... workflow steps ...
submit_time = time.time()
age = submit_time - token_received_at
logger.info(f"Submitting token, age: {age:.1f}s")
if age > 270:
logger.warning(f"Token may be expired (age: {age:.1f}s > 270s safety limit)")
التحديث التلقائي في عنصر Turnstile داخل المتصفح
في التدفقات التي تعمل داخل متصفح فعلي، يُحدّث عنصر Turnstile الرموز تلقائيًا قبل انتهاء صلاحيتها، ويُطلق data-expired-callback عند انقضاء العمر:
turnstile.render('#captcha', {
sitekey: '0x4AAAA...',
callback: (token) => {
console.log('New token:', token);
},
'expired-callback': () => {
console.log('Token expired — widget will auto-refresh');
}
});
خلاصة الفرق بين الحالتين:
- داخل المتصفح: يتكفّل عنصر Turnstile بتحديث الرمز تلقائيًا قبل انتهائه
- عبر الـ API فقط بلا متصفح: إدارة حداثة الرمز مسؤوليتك أنت بالكامل
سيناريو من واقع الاستخدام في المنطقة
تخيّل منصة خدمات إلكترونية عربية تتطلب تسجيلًا من عدة خطوات: بيانات شخصية، ثم عنوان، ثم اختبار Cloudflare Turnstile، ثم مراجعة وتأكيد. الكثير من مستخدمي المنطقة يتصفّحون عبر شبكات محمول تتذبذب فيها زمن الاستجابة بشكل ملحوظ في أوقات الذروة. إذا حلّ سكربت الأتمتة اختبار CAPTCHA في منتصف التدفق ثم انتظر تحميل صفحتَي المراجعة والتأكيد على اتصال بطيء، فقد يتجاوز عمر الرمز حاجز الخمس دقائق قبل الوصول إلى زر الإرسال. الدرس عملي وبسيط، ويمكن تلخيصه في ثلاث قواعد:
- أخّر حل Turnstile إلى الخطوة الأخيرة قبل الإرسال مباشرةً
- افترض دائمًا زمن استجابة أبطأ من بيئة الاختبار عند حساب الهامش
- سجّل عمر الرمز عند الإرسال حتى تكتشف الأنماط البطيئة مبكرًا
الأسئلة الشائعة
ما الفرق بين رمز منتهي الصلاحية ورمز سبق استهلاكه؟
الرمز المنتهي هو رمز تجاوز عمره الافتراضي (نحو 300 ثانية) دون أن يُستخدم. أما الرمز المُستهلَك فهو رمز صالح زمنيًا لكن الموقع قبله بالفعل مرة واحدة، ورموز Turnstile تُستخدم لمرة واحدة فقط. كلا الحالتين تُنتج فشلًا متشابهًا في المظهر، والحل واحد: اطلب رمزًا جديدًا.
هل تختلف مهلة Turnstile عن reCAPTCHA وhCaptcha؟
نعم. يمنح Turnstile نحو 300 ثانية، بينما تقتصر reCAPTCHA وhCaptcha على نحو 120 ثانية تقريبًا. هذا يجعل هامش الخطأ في Turnstile أوسع، لكن لا تعتمد عليه في التدفقات الطويلة؛ اعتمد دائمًا حد أمان قدره 270 ثانية.
كيف أتعامل مع انتهاء الصلاحية في النماذج متعددة الخطوات؟
أعِد ترتيب التدفق بحيث يكون حل Turnstile آخر خطوة قبل الإرسال. املأ كل الحقول وتنقّل بين الصفحات أولًا، ثم احلّ الرمز وأرسله فورًا. بهذا تُبقي عمر الرمز في نطاق الثواني، لا الدقائق.
هل يحل CaptchaAI رمز Cloudflare Turnstile؟
نعم، Cloudflare Turnstile مدعوم بشكل كامل عبر الـ API باستخدام طريقة turnstile، وغالبًا ما يكتمل الحل في أقل من 10 ثوانٍ. تبقى إدارة توقيت الإرسال بعد استلام الرمز مسؤوليتك أنت داخل سير العمل.
جدول استكشاف الأخطاء الشائعة
| المشكلة | السبب | الحل |
|---|---|---|
| ينجح الرمز في الاختبار ويفشل في الإنتاج | سير عمل الإنتاج أبطأ فتنقضي المهلة | احلّ الرمز في اللحظة الأخيرة لا مسبقًا |
| المحاولة الأولى تنجح والإعادات تفشل | إعادة استخدام رمز سبق استهلاكه | اطلب رمزًا جديدًا لكل محاولة |
| فشل متقطّع في النماذج الطويلة | انتهاء الرمز أثناء التدفق متعدد الخطوات | انقل حل CAPTCHA إلى الخطوة الأخيرة |
| نسبة فشل مرتفعة في المهام الدُفعية | رموز حُلّت جماعيًا انتهت قبل استخدامها | احلّ عند الطلب لا دُفعةً واحدة |
الخطوات التالية
- ابدأ سريعًا مع CaptchaAI: أول عملية حل خلال دقائق
- حل reCAPTCHA v2 عبر الـ API خطوة بخطوة
- حل Cloudflare Turnstile عبر الـ API
- حل GeeTest v3 عبر الـ API