reCAPTCHA проверяет, что токены используются в том же домене, для которого они были созданы. Если существует несоответствие между конфигурацией домена CAPTCHA и фактическим источником запроса, вы получаете ошибки проверки домена. Эти сбои происходят молчаливо — токен кажется действительным, но сервер его отклоняет. В этом руководстве описаны все сценарии ошибок, связанных с доменом, и способы их устранения.
Как работает проверка домена
Site owner registers reCAPTCHA → adds allowed domains (example.com, www.example.com)
↓
reCAPTCHA widget loads on example.com → matches allowed domain ✓
↓
Token generated with embedded hostname
↓
Server validates token via siteverify API
↓
Google checks: Does token hostname match allowed domains?
├─ YES → { "success": true, "hostname": "example.com" }
└─ NO → { "success": false, error or hostname mismatch }
Где проверяется домен
| Контрольно-пропускной пункт | Что проверено |
|---|---|
| На стороне клиента | Виджет загружается только на разрешенных доменах (необязательно — можно отключить) |
| Генерация токена | Имя хоста, встроенное в токен, соответствует источнику страницы |
| Проверка сервера | siteverify возвращает имя хоста — сервер должен проверить его совпадение |
Распространенные ошибки проверки домена
Ошибка 1: несоответствие имени хоста в ответе siteverify.
{
"success": true,
"hostname": "subdomain.example.com",
"challenge_ts": "2025-01-15T10:30:00Z"
}
Токен действителен, но в поле hostname указан другой домен, чем ожидалось. Некоторые реализации сервера отвергают это:
# Server-side validation that checks hostname
def validate_token(token, secret_key, expected_hostname):
result = requests.post(
"https://www.google.com/recaptcha/api/siteverify",
data={"secret": secret_key, "response": token},
).json()
if not result.get("success"):
return False
# This check causes failures when hostnames don't match
if result.get("hostname") != expected_hostname:
return False # Domain mismatch!
return True
Причины:
- Токен решен для
www.example.com, но проверен наexample.com. - Токен решен для
staging.example.com, но проверен наexample.com. - Прокси или CDN меняют видимое имя хоста
Исправление: Убедитесь, что pageurl в запросе решателя точно соответствует домену, куда будет отправлен токен.
Ошибка 2: виджет отказывается загружаться.
Виджет reCAPTCHA показывает ошибку или не отображается:
ERROR: Invalid domain for site key
Причины:
- Разрешенные домены ключа сайта не включают домен текущей страницы.
- Загрузка виджета с локального хоста или файла: протокол //
- Использование IP-адреса вместо доменного имени
Исправление автоматизации. Это проблема конфигурации владельца сайта. Для решения убедитесь, что вы передали правильный pageurl, соответствующий разрешенному домену.
Ошибка 3: токен отклонен, несмотря на правильное решение
{
"success": false,
"error-codes": ["invalid-input-response"]
}
Токен был создан для домена, отличного от того, в котором он проверяется.
Распространенная причина автоматизации: pageurl, отправленный решателю, не соответствует фактическому целевому домену:
# WRONG: pageurl doesn't match actual target
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": "https://https://staging.example.com/qa-login", # ← Must match actual domain
"json": 1,
})
# But submitting token to:
requests.post("https://app.https://staging.example.com/qa-login", ...) # Different subdomain!
Правила сопоставления доменов
Точное совпадение с подстановочным знаком
Проверка домена reCAPTCHA по умолчанию не является строгой проверкой субдомена. Поведение зависит от конфигурации владельца сайта:
| Зарегистрированный домен | Приемлемое происхождение |
|---|---|
example.com |
example.com, www.example.com, sub.example.com (если подстановочный знак включен) |
www.example.com |
Только www.example.com (если строго) |
*.example.com |
Любой субдомен example.com |
localhost |
Только localhost (для разработки) |
Поведение имени хоста на стороне сервера
При проверке через siteverify hostname в ответе отражает страницу, на которой был сгенерирован токен. Сервер владельца сайта решает, принимать ли его:
# Permissive validation (accepts any subdomain)
def validate_permissive(token, secret, base_domain):
result = requests.post(
"https://www.google.com/recaptcha/api/siteverify",
data={"secret": secret, "response": token},
).json()
if not result.get("success"):
return False
hostname = result.get("hostname", "")
return hostname == base_domain or hostname.endswith(f".{base_domain}")
# Strict validation (exact match only)
def validate_strict(token, secret, expected_hostname):
result = requests.post(
"https://www.google.com/recaptcha/api/siteverify",
data={"secret": secret, "response": token},
).json()
return result.get("success") and result.get("hostname") == expected_hostname
Исправление доменных ошибок в автоматизации
Исправление 1: точное совпадение URL-адреса страницы
Самое распространенное решение — убедиться, что pageurl соответствует фактической цели:
# Correct: pageurl matches where you'll submit the token
target_url = "https://www.https://staging.example.com/qa-login"
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
"pageurl": target_url, # Must match the actual domain
"json": 1,
})
Исправление 2. Обработка www и не-www
from urllib.parse import urlparse
def normalize_url(url):
"""Normalize URL for consistent domain matching."""
parsed = urlparse(url)
# Use exactly what the target site uses
# Check if the site redirects www → non-www or vice versa
return f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
# Test which variant the site uses
response = requests.get("https://https://staging.example.com/qa-login", allow_redirects=True)
actual_url = response.url # May be https://www.https://staging.example.com/qa-login after redirect
Исправление 3. Определите правильный домен из цепочки перенаправления.
Некоторые сайты перенаправляются через несколько доменов:
def get_final_url(url):
"""Follow redirects to find the actual CAPTCHA page domain."""
response = requests.get(url, allow_redirects=True, timeout=15)
return response.url
# Login URL might redirect:
# https://https://staging.example.com/qa-login → https://auth.https://staging.example.com/qa-login
final_url = get_final_url("https://https://staging.example.com/qa-login")
# Use final_url as pageurl for solver
Исправление 4. Извлеките домен из URL-адреса обратного вызова reCAPTCHA.
from bs4 import BeautifulSoup
from urllib.parse import urlparse
def extract_recaptcha_domain(html, page_url):
"""Extract the domain reCAPTCHA uses for token binding."""
soup = BeautifulSoup(html, "html.parser")
# Check for reCAPTCHA iframe
iframe = soup.find("iframe", src=lambda s: s and "recaptcha" in s)
if iframe:
src = iframe.get("src", "")
# The iframe URL may contain the domain parameter
if "domain=" in src:
# Extract domain from iframe URL
pass
# Default: use the page URL's domain
return urlparse(page_url).netloc
Диагностический инструмент проверки домена
import requests
from urllib.parse import urlparse
class DomainDiagnostic:
"""Diagnose domain verification issues for reCAPTCHA solving."""
def __init__(self, target_url):
self.target_url = target_url
self.issues = []
def check_redirects(self):
"""Check if the URL redirects to a different domain."""
try:
response = requests.get(
self.target_url, allow_redirects=True, timeout=15,
headers={"User-Agent": "Mozilla/5.0 Chrome/120.0.0.0"},
)
final_url = response.url
original_domain = urlparse(self.target_url).netloc
final_domain = urlparse(final_url).netloc
if original_domain != final_domain:
self.issues.append({
"type": "redirect",
"message": f"Redirects from {original_domain} to {final_domain}",
"fix": f"Use pageurl: {final_url}",
})
return final_url
except Exception as e:
self.issues.append({"type": "error", "message": str(e)})
return self.target_url
def check_www_variant(self):
"""Check if www and non-www point to the same content."""
parsed = urlparse(self.target_url)
domain = parsed.netloc
if domain.startswith("www."):
alt_domain = domain[4:]
else:
alt_domain = f"www.{domain}"
alt_url = self.target_url.replace(domain, alt_domain)
try:
alt_response = requests.get(alt_url, allow_redirects=True, timeout=10)
alt_final = urlparse(alt_response.url).netloc
if alt_final != domain and alt_final != alt_domain:
self.issues.append({
"type": "www_redirect",
"message": f"{alt_domain} redirects to {alt_final}",
})
except Exception:
pass
def report(self):
"""Generate diagnostic report."""
final_url = self.check_redirects()
self.check_www_variant()
print(f"Target URL: {self.target_url}")
print(f"Final URL: {final_url}")
print(f"Use as pageurl: {final_url}")
if self.issues:
print("\nIssues found:")
for issue in self.issues:
print(f" [{issue['type']}] {issue['message']}")
if "fix" in issue:
print(f" Fix: {issue['fix']}")
else:
print("\nNo domain issues detected.")
# Usage
diag = DomainDiagnostic("https://https://staging.example.com/qa-login")
diag.report()
Таблица устранения неполадок
| Симптом | Вероятная причина | Диагностика | Исправить |
|---|---|---|---|
| Токен всегда отклоняется | pageurl не соответствует целевому домену | Сравните pageurl решателя с фактическим доменом отправки | Обновите URL-адрес страницы, чтобы он соответствовал |
| На www работает, на не www работает. | Несоответствие варианта домена | Проверьте поведение перенаправления | Используйте вариант, который использует целевой сайт (следуйте перенаправлениям). |
| Иногда работает, иногда не работает | CDN или балансировщик нагрузки обслуживают разные домены | Проверьте, меняется ли домен в зависимости от запроса | Используйте согласованный URL-адрес из цепочки переадресации. |
| Работает в браузере, не работает в скрипте | Скрипт отправляется из другого источника | Сравните строку URL-адреса браузера с URL-адресом страницы скрипта. | Сопоставить конечный URL-адрес браузера |
| Корпоративный токен отклонен | Неправильная привязка проекта или домена | Убедитесь, что ключ корпоративного сайта соответствует домену | Проверьте настройки домена корпоративной консоли |
Часто задаваемые вопросы
CaptchaAI автоматически выполняет проверку домена?
CaptchaAI генерирует токены, привязанные к предоставленному вами pageurl. Вы должны убедиться, что этот URL-адрес соответствует домену, куда вы отправите токен. CaptchaAI не проверяет конфигурацию домена — он использует любой указанный вами URL-адрес страницы.
Могу ли я решить CAPTCHA для одного домена и использовать ее в другом?
Нет. Токены reCAPTCHA привязаны к домену, для которого они были созданы. Токен, сгенерированный для example.com, нельзя использовать в other-site.com. Даже разные поддомены могут дать сбой, если сайт строго проверяет имя хоста.
Почему мой токен работает при тестировании, но не работает в рабочей среде?
Распространенные причины: (1) При тестировании используется localhost с другими правилами домена, (2) В рабочей среде используется CDN с другим доменом, (3) В рабочей среде применяется более строгая проверка имени хоста, (4) В рабочей среде другой путь URL-адреса или цепочка перенаправления.
Имеет ли значение путь или только домен?
ReCAPTCHA проверяет только домен (имя хоста). Путь (/login, /signup) не влияет на проверку домена. Однако вам все равно следует использовать правильный полный URL-адрес pageurl, поскольку некоторые реализации решателя могут использовать его для других целей.
Краткое содержание
Проверка домена reCAPTCHA связывает токены с именем хоста, на котором они были сгенерированы. Наиболее распространенной ошибкой автоматизации является несоответствие pageurl — URL-адрес, передаваемыйCaptchaAIдолжен соответствовать домену, куда будет отправлен токен. Следуйте перенаправлениям, чтобы найти реальный домен, обрабатывать варианты с www и без www и использовать инструмент диагностики домена для выявления несоответствий перед решением.
Похожие статьи
- Как решить обратный вызов Recaptcha V2 с помощью API
- Cloudflare Turnstile Recaptcha V2. Обработка на той же площадке.
- Распространенные ошибки и исправления капчи в виде сетки