Найден корректный robots.txt
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Robots.txt настроен корректно. Размер файла: 19862 байт. Загружен за: 0сек.
Проверяемая страница не запрещена в robots.txt.
Цепочка редиректов для файла robots.txt:
http://asergroup.ru/robots.txt
301 MovedPermanently
https://asergroup.ru/robots.txt
200 OK
Показать содержимое robots.txt
<!-- challenge.html (same as before) -->
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BotShield Challenge</title>
<style>body { margin: 0; padding: 0; box-sizing: border-box; }
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root { --sv-item-width: 50px; --sv-item-height: 50px; --sv-gap: 8px; --sv-padding: 20px; }
.sv-captcha {
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
min-width: 100vw; min-height: 100vh; margin: 0; padding: 0;
display: flex; justify-content: center; align-items: center;
background-color: rgba(0, 0, 0, 0.5); z-index: 9999999;
}
.sv-captcha.loading { pointer-events: none; }
.sv-captcha-inner {
padding: var(--sv-padding); background-color: rgba(255, 255, 255, 0.95);
border-radius: 20px; box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
width: 100%; max-width: calc((var(--sv-item-width) + var(--sv-gap)) * 4 + var(--sv-item-width) + (var(--sv-padding) * 2)); text-align: center;
}
.sv-captcha h2 { font-size: 16px; margin-bottom: 15px; }
.sv-captcha .sv-captcha-items { position: relative; touch-action: none; height: var(--sv-item-height); }
.sv-captcha .sv-captcha-item {
position: absolute; top: 0; left: 0; width: var(--sv-item-width); height: var(--sv-item-height);
background-color: #FFFFFF; background-position: center; background-repeat: no-repeat; background-size: cover;
border-radius: 10px; user-select: none; cursor: grab; transition: left 0.3s; -webkit-tap-highlight-color: transparent;
}
.sv-captcha .sv-captcha-item.grabbing { cursor: grabbing; transition: none; z-index: 999999; }
.check-sv-captcha {
position: relative; display: block; width: 100%; padding: 10px; margin-top: 15px; height: 42px;
border: none; border-radius: 8px; cursor: pointer; background-color: grey; outline: none;
user-select: none; -webkit-tap-highlight-color: transparent;
}
.check-sv-captcha.loading { pointer-events: none; opacity: 0.7; }
.check-sv-captcha .loader {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
display: flex; align-items: center; justify-content: center;
}
.check-sv-captcha .loader::before {
content: ''; width: 25px; height: 25px; border: 3px solid #FFF; border-bottom-color: transparent;
border-radius: 50%; display: inline-block; box-sizing: border-box; animation: rotation 1s linear infinite;
}
.sv-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 15px;
min-height: 150px;
background-color: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 20px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}
.sv-loading h1 {
font-size: 20px;
color: #1c2526;
margin: 0;
font-weight: 500;
}
.sv-loading .loader {
display: flex;
align-items: center;
justify-content: center;
/* width: 40px; */
height: 70px;
}
.sv-loading .loader::before {
content: '';
width: 40px;
height: 40px;
border: 5px solid #007aff;
border-bottom-color: transparent;
border-radius: 50%;
display: inline-block;
box-sizing: border-box;
animation: rotation 1s linear infinite;
}
@keyframes rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.message { color: red; text-align: center; margin-top: 10px; }
.apple.sv-captcha {
background-color: rgba(0, 0, 0, 0.4); position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
min-width: 100vw; min-height: 100vh; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center;
}
.apple .sv-captcha-inner {
background-color: rgba(255, 255, 255, 0.95); border-radius: 20px; padding: var(--sv-padding);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); width: 100%;
}
.apple.sv-captcha h2 { font-family: sans-serif; font-size: 18px; font-weight: 600; color: #1c2526; }
.apple.sv-captcha .sv-captcha-item {
background-color: #FFFFFF; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.apple.sv-captcha .sv-captcha-item.grabbing {
transform: scale(1.05); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.apple .check-sv-captcha {
background-color: #007aff; color: #FFFFFF; padding: 12px; font-family: sans-serif;
font-size: 16px; font-weight: 500; border-radius: 12px;
}
@media (hover: hover) { .apple .check-sv-captcha:hover { background-color: #0062cc; } }
.apple .check-sv-captcha:active { background-color: #0051a8; }
@media (prefers-color-scheme: dark) {
.apple.sv-captcha { background-color: rgba(0, 0, 0, 0.7); }
.apple .sv-captcha-inner { background-color: rgba(28, 28, 30, 0.95); box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3); }
.apple.sv-captcha h2 { color: #ffffff; }
.apple.sv-captcha .sv-loading h1 { color: #ffffff; }
.apple.sv-captcha .sv-captcha-item { background-color: #2c2c2e; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); }
.apple.sv-captcha .sv-captcha-item.grabbing { background-color: #363638; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); }
.apple .check-sv-captcha { background-color: #0a84ff; }
@media (hover: hover) { .apple .check-sv-captcha:hover { background-color: #007aff; } }
.apple .check-sv-captcha:active { background-color: #0066cc; }
}
.android.sv-captcha {
background-color: rgba(0, 0, 0, 0.5); position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
min-width: 100vw; min-height: 100vh; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center;
}
.android .sv-captcha-inner {
background-color: #ffffff; border-radius: 16px; padding: var(--sv-padding);
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15); width: 100%;
}
.android.sv-captcha h2 {
font-family: 'Roboto', sans-serif; font-size: 18px; font-weight: 500; color: #202124; margin-bottom: 16px;
}
.android.sv-captcha .sv-captcha-item {
background-color: #f5f5f5; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.android.sv-captcha .sv-captcha-item.grabbing {
transform: scale(1.03); background-color: #eeeeee; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); transition: transform 0.1s, background-color 0.1s;
}
.android .check-sv-captcha {
background-color: #6200ee; color: #ffffff; padding: 12px; font-family: 'Roboto', sans-serif;
font-size: 16px; font-weight: 500; border-radius: 8px; text-transform: uppercase; letter-spacing: 0.5px;
}
@media (hover: hover) { .android .check-sv-captcha:hover { background-color: #7c4dff; } }
.android .check-sv-captcha:active { background-color: #3700b3; }
@media (prefers-color-scheme: dark) {
.android.sv-captcha { background-color: rgba(0, 0, 0, 0.7); }
.android .sv-captcha-inner { background-color: #212121; border-radius: 16px; padding: var(--sv-padding); box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25); }
.android.sv-captcha h2 { font-family: 'Roboto', sans-serif; font-size: 18px; font-weight: 500; color: #ffffff; margin-bottom: 16px; }
.android.sv-captcha .sv-loading h1 { color: #ffffff; }
.android.sv-captcha .sv-captcha-item { background-color: #303030; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); }
.android.sv-captcha .sv-captcha-item.grabbing { transform: scale(1.03); background-color: #424242; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); transition: transform 0.1s, background-color 0.1s; }
.android .check-sv-captcha { background-color: #bb86fc; color: #ffffff; padding: 12px; font-family: 'Roboto', sans-serif; font-size: 16px; font-weight: 500; border-radius: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
@media (hover: hover) { .android .check-sv-captcha:hover { background-color: #d1aaff; } }
.android .check-sv-captcha:active { background-color: #985eff; }
}</style>
</head>
<body>
<div class="sv-captcha">
<div class="sv-captcha-inner">
<div class="sv-loading" style="display: block;">
<h1>Checking browser...</h1>
<div class="loader"></div>
</div>
<div class="sv-captcha-content" style="display: none;">
<h2>Перетаскивайте элементы в порядке возрастания</h2>
<div class="sv-captcha-items"></div> <!-- Placeholder -->
<button class="check-sv-captcha">Проверить</button>
<div class="message"></div>
</div>
</div>
</div>
<input type="hidden" id="challenge_id" value="e00a00330532e8ed7016544ae385c2c3">
<input type="hidden" id="is_soft" value="true">
<script>let draggableItems = null;
async function hashFingerprint(str) {
const msgBuffer = new TextEncoder().encode(str);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
function detectDevice() {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
if ((/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) || /Macintosh/.test(userAgent)) return 'apple';
if (/android/i.test(userAgent)) return 'android';
return 'apple';
}
async function generateFingerprint() {
const canvas = document.createElement('canvas');
canvas.width = 100; canvas.height = 100;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = '#FFFFFF'; ctx.font = '20px sans-serif';
ctx.fillText('test', 10, 50);
const userAgent = navigator.userAgent;
const canvasData = canvas.toDataURL();
const result = await hashFingerprint(canvasData + userAgent);
return result;
}
async function generateComplexFingerprint() {
const canvas = document.createElement('canvas');
canvas.width = 100; canvas.height = 100;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = '#FFFFFF'; ctx.font = '20px sans-serif';
ctx.fillText('test', 10, 50);
const userAgent = navigator.userAgent;
const canvasData = canvas.toDataURL();
const screen = `${window.screen.width}x${window.screen.height}`;
const fonts = window.navigator.fonts ? Array.from(window.navigator.fonts).map(f => f.family).join(',') : 'unknown';
const data = `${canvasData}:${userAgent}:${screen}:${fonts}`;
const result = await hashFingerprint(data);
return result;
}
function getChallengeId() {
const input = document.getElementById('challenge_id');
if (input && input.value) return input.value;
const matches = document.cookie.match(new RegExp("(?:^|; )bs_challenge_id=([^;]*)"));
return matches ? decodeURIComponent(matches[1]) : null;
}
function isSoftChallenge() {
return document.getElementById('is_soft').value === 'true';
}
class DraggableItems {
constructor(config = {}) {
this.containerSelector = config.containerSelector || '.sv-captcha-items';
this.itemSelector = config.itemSelector || '.sv-captcha-item';
this.buttonSelector = config.buttonSelector || '.check-sv-captcha';
this.items = [];
this.element = null;
this.inputX = 0;
this.offsetX = 0;
this.raf = null;
this.slotSize = 0;
this.maxSlots = 0;
this.positions = [];
this.gap = 0;
this.containerOffset = 0;
this.init();
}
init() {
this.items = document.querySelectorAll(`${this.containerSelector} ${this.itemSelector}`);
if (!this.items.length) return;
this.maxSlots = this.items.length;
this.setupContainer();
this.setupPositions();
this.addEventListeners();
this.initSyncButton();
window.addEventListener('resize', () => this.handleResize());
}
setupContainer() {
const firstItem = this.items[0];
const computedStyle = getComputedStyle(firstItem);
const container = document.querySelector(this.containerSelector);
const containerRect = container.getBoundingClientRect();
this.slotSize = parseFloat(computedStyle.width);
this.gap = parseFloat(getComputedStyle(document.body).getPropertyValue('--sv-gap') || 0);
container.style.width = `${this.maxSlots * this.slotSize + (this.maxSlots - 1) * this.gap}px`;
this.containerOffset = containerRect.left;
}
setupPositions() {
this.positions = Array.from(this.items).map((item, key) => ({ element: item, slot: key }));
this.updatePositions();
}
updatePositions() {
this.positions.forEach(pos => {
if (pos.element !== this.element) {
pos.element.style.left = `${pos.slot * (this.slotSize + this.gap)}px`;
}
});
}
addEventListeners() {
document.addEventListener('mousedown', (e) => this.handlePress(e));
document.addEventListener('touchstart', (e) => this.handlePress(e), { passive: false });
}
initSyncButton() {
const syncButton = document.querySelector(this.buttonSelector);
if (syncButton) syncButton.addEventListener('click', () => this.syncDomWithPositions());
}
syncDomWithPositions() {
const container = document.querySelector(this.containerSelector);
this.positions.forEach(pos => container.appendChild(pos.element));
this.updatePositions();
}
handlePress(event) {
const target = event.target;
if (!target.matches(this.itemSelector)) return;
event.preventDefault();
this.element = target;
this.element.classList.add('grabbing');
const isTouch = event.type === 'touchstart';
const clientX = isTouch ? event.touches[0].clientX : event.clientX;
const bbox = this.element.getBoundingClientRect();
this.inputX = clientX;
this.offsetX = this.inputX - bbox.left;
this.setupMoveListeners(isTouch);
this.raf = requestAnimationFrame(() => this.updateDragging());
}
setupMoveListeners(isTouch) {
if (isTouch) {
document.addEventListener('touchmove', (e) => this.handleMove(e), { passive: false });
document.addEventListener('touchend', (e) => this.handleRelease(e), { passive: false });
} else {
document.addEventListener('mousemove', (e) => this.handleMove(e));
document.addEventListener('mouseup', (e) => this.handleRelease(e));
}
}
handleMove(event) {
const isTouch = event.type === 'touchmove';
this.inputX = isTouch ? event.touches[0].clientX : event.clientX;
}
updateDragging() {
if (!this.element) return;
let newLeft = this.inputX - this.offsetX - this.containerOffset;
newLeft = Math.max(0, Math.min(newLeft, (this.maxSlots - 1) * (this.slotSize + this.gap)));
this.element.style.left = `${newLeft}px`;
const mouseSlot = Math.round(newLeft / (this.slotSize + this.gap));
const boundedSlot = Math.max(0, Math.min(mouseSlot, this.maxSlots - 1));
const draggedIndex = this.positions.findIndex(pos => pos.element === this.element);
const draggedPos = this.positions[draggedIndex];
if (boundedSlot !== draggedPos.slot) {
this.positions.splice(draggedIndex, 1);
this.positions.splice(boundedSlot, 0, draggedPos);
this.positions.forEach((pos, index) => pos.slot = index);
this.updatePositions();
}
this.raf = requestAnimationFrame(() => this.updateDragging());
}
handleRelease(event) {
if (!this.element) return;
this.element.classList.remove('grabbing');
const newLeft = parseFloat(this.element.style.left);
const finalSlot = Math.round(newLeft / (this.slotSize + this.gap));
this.element.style.left = `${finalSlot * (this.slotSize + this.gap)}px`;
this.cleanup(event);
}
getCurrentOrder() {
return this.positions.map(pos => pos.element.dataset.index).join('');
}
cleanup(event) {
this.element = null;
const isTouch = event.type === 'touchend';
if (isTouch) {
document.removeEventListener('touchmove', (e) => this.handleMove(e));
document.removeEventListener('touchend', (e) => this.handleRelease(e));
} else {
document.removeEventListener('mousemove', (e) => this.handleMove(e));
document.removeEventListener('mouseup', (e) => this.handleRelease(e));
}
if (this.raf) {
cancelAnimationFrame(this.raf);
this.raf = null;
}
}
handleResize() {
this.setupContainer();
this.updatePositions();
if (this.element) {
const newLeft = this.inputX - this.offsetX - this.containerOffset;
this.element.style.left = `${Math.max(0, Math.min(newLeft, (this.maxSlots - 1) * (this.slotSize + this.gap)))}px`;
}
}
}
async function fetchWithRetry(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) throw new Error(`HTTP error ${response.status}`);
return response;
} catch (err) {
throw err;
}
}
async function loadCaptcha() {
const challengeId = getChallengeId();
if (!challengeId) return;
try {
const response = await fetchWithRetry('/cgi-bin/botshield/challenge/get-captcha', {
method: 'GET',
credentials: 'include'
});
const data = await response.json();
const itemsContainer = document.querySelector('.sv-captcha-items');
itemsContainer.innerHTML = data.captchaItemsHTML;
itemsContainer.style.display = 'block';
const contentSection = document.querySelector('.sv-captcha-content');
contentSection.style.display = 'block';
const loadingSection = document.querySelector('.sv-loading');
loadingSection.style.display = 'none';
const captchaSection = document.querySelector('.sv-captcha');
captchaSection.classList.add(detectDevice());
draggableItems = new DraggableItems({ containerSelector: '.sv-captcha-items', itemSelector: '.sv-captcha-item', buttonSelector: '.check-sv-captcha' });
const checkButton = document.querySelector('.check-sv-captcha');
if (checkButton) checkButton.addEventListener('click', submitCaptcha);
} catch (err) {
console.error('Load captcha error:', err.message);
document.body.innerHTML = '<h1>Ошибка загрузки капчи: ' + err.message + '</h1>';
}
}
async function runChallenge() {
const challengeId = getChallengeId();
if (!challengeId) {
document.body.innerHTML = '<h1>Ошибка: Нет challengeId</h1>';
return;
}
const fingerprint = await generateFingerprint();
const complexFingerprint = await generateComplexFingerprint();
const postPath = isSoftChallenge() ? '/cgi-bin/botshield/soft-challenge' : '/cgi-bin/botshield/challenge';
try {
const response = await fetchWithRetry(postPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fingerprint, complexFingerprint, challengeId }),
credentials: 'include'
});
const data = await response.json();
if (data.success) {
setTimeout(() => window.location.reload(), 500);
return;
} else if (data.error === 'Complete CAPTCHA') {
await loadCaptcha();
} else if (data.error === 'Too many attempts') {
document.body.innerHTML = '<h1>Слишком много попыток, попробуйте позже</h1>';
} else {
const messageElement = document.querySelector('.message');
if (messageElement) messageElement.textContent = data.error || 'Ошибка';
await loadCaptcha();
}
} catch (err) {
console.error('Fetch error:', err.message);
await loadCaptcha();
}
}
async function submitCaptcha() {
if (!draggableItems) return;
draggableItems.syncDomWithPositions();
const sendingKey = draggableItems.getCurrentOrder();
const challengeId = getChallengeId();
if (!challengeId) {
await loadCaptcha();
return;
}
const fingerprint = await generateFingerprint();
const complexFingerprint = await generateComplexFingerprint();
const postPath = isSoftChallenge() ? '/cgi-bin/botshield/soft-challenge' : '/cgi-bin/botshield/challenge';
try {
const response = await fetchWithRetry(postPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fingerprint, complexFingerprint, challengeId, captchaAnswer: sendingKey }),
credentials: 'include'
});
const data = await response.json();
if (data.success) {
window.location.reload();
} else if (data.error === 'Too many attempts') {
document.body.innerHTML = '<h1>Слишком много попыток, попробуйте позже</h1>';
} else {
const messageElement = document.querySelector('.message');
if (messageElement) messageElement.textContent = data.error || 'Неверно';
const itemsContainer = document.querySelector('.sv-captcha-items');
itemsContainer.innerHTML = '';
await loadCaptcha();
}
} catch (err) {
console.error('Submit error:', err.message);
await loadCaptcha();
}
}
setTimeout(runChallenge, 0);</script>
</body>
</html>