Блокировка доступа по стране для отдельных страниц сайта uCoz с помощью JavaScript

Юрий Герук 2026-01-03 36
Блокировка доступа по стране для отдельных страниц сайта uCoz с помощью JavaScript

Введение

Иногда задача стоит не в том, чтобы закрыть весь сайт целиком, а ограничить доступ только к конкретным страницам. Например, к отдельной статье, лендингу, разделу с чувствительным контентом или служебной информации.

В uCoz есть системные инструменты ограничения доступа по странам, но у них есть важная особенность: они работают сразу на весь сайт. Если включить такое ограничение на уровне системы, посетители из выбранных стран не смогут открыть ни одну страницу сайта вообще.

Когда нужно более гибкое поведение и блокировать доступ только на отдельных страницах, удобнее использовать JavaScript решение.

Сразу честно. Это не серверная защита. Это интерфейсное ограничение, которое выполняется в браузере пользователя. Для задач информирования, соблюдения формальных требований и ограничения отображения контента этого обычно достаточно.

В чем суть подхода

Решение работает так.

  1. Пользователь открывает страницу.
  2. Контент страницы временно скрыт.
  3. JavaScript делает запрос к публичному GeoIP сервису.
  4. Сервис определяет страну посетителя по IP адресу.
  5. Если страна входит в список запрещенных, страница полностью заменяется на уведомление о недоступности.
  6. Если страна разрешена, страница отображается как обычно.

Ключевой момент

Код размещается только на нужной странице, поэтому ограничение действует локально и не затрагивает остальные разделы сайта.

Почему используется внешний GeoIP сервис

В браузере нет способа определить страну пользователя без обращения к внешнему сервису. В данном решении используется публичный GeoIP API, который:

  • работает по HTTPS;
  • не требует регистрации;
  • не требует API ключа;
  • возвращает код и название страны.

Это позволяет использовать решение сразу после вставки кода, без дополнительных настроек сайта.

Готовое решение для uCoz

Код ниже полностью самодостаточный. Все стили встроены внутрь, поэтому он корректно работает даже при полной замене содержимого страницы.

Его можно вставить:

  • в HTML код конкретной страницы;
  • в шаблон конкретного материала;
  • в текстовый блок на нужной странице.
<script>
(function () {
 "use strict";

 var BLOCKED = ["RU", "BY"]; // список заблокированных стран
 var SUPPORT_EMAIL = ""; // почта поддержки, можно оставить пустым
 var HOME_URL = "/"; // ссылка на главную

 function showPage() {
 document.documentElement.style.visibility = "visible";
 }

 function escapeHtml(s) {
 return String(s).replace(/[&<>"']/g, function (c) {
 return ({ "&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;" })[c];
 });
 }

 function escapeAttr(s) {
 return String(s).replace(/"/g, "&quot;");
 }

 function renderBlock(countryCode, countryName) {
 var cc = (countryCode || "??").toUpperCase();
 var cn = (countryName || "Неизвестная страна");
 var blockedList = BLOCKED.join(", ");

 var contactBtn = SUPPORT_EMAIL
 ? '<a class="geo-btn geo-btn-secondary" href="mailto:' + encodeURIComponent(SUPPORT_EMAIL) + '">✉️ Написать в поддержку</a>'
 : "";

 var css =
 "<style>" +
 "html,body{height:100%;margin:0;}" +
 ".geo-block-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:28px;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;background:#0b0f19;color:#e7eaf3;}" +
 ".geo-block-card{width:min(820px,100%);background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:18px;box-shadow:0 12px 40px rgba(0,0,0,.35);padding:22px;}" +
 ".geo-block-icon{width:46px;height:46px;border-radius:14px;display:grid;place-items:center;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.14);font-size:22px;}" +
 ".geo-block-title{margin:12px 0 6px;font-size:22px;}" +
 ".geo-block-sub{margin:0;color:rgba(231,234,243,.82);}" +
 ".geo-block-badges{margin-top:14px;display:flex;flex-wrap:wrap;gap:8px;}" +
 ".geo-badge{padding:8px 10px;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);font-size:13px;}" +
 ".geo-block-actions{margin-top:18px;display:flex;gap:10px;flex-wrap:wrap;}" +
 ".geo-btn{border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.10);color:#fff;padding:10px 12px;border-radius:12px;font-weight:600;text-decoration:none;}" +
 ".geo-btn:hover{background:rgba(255,255,255,.14);}" +
 ".geo-legal{margin-top:14px;font-size:13px;color:rgba(231,234,243,.62);}" +
 "</style>";

 var html =
 '<div class="geo-block-wrap">' +
 '<div class="geo-block-card">' +
 '<div class="geo-block-icon">⛔</div>' +
 '<h2 class="geo-block-title">Доступ для данной страны ограничен.</h2>' +
 '<p class="geo-block-sub">Контент недоступен для посетителей из страны <b>' + escapeHtml(cn) + '</b>.</p>' +
 '<div class="geo-block-badges">' +
 '<span class="geo-badge">🌍 ' + escapeHtml(cn) + ' (' + escapeHtml(cc) + ')</span>' +
 '<span class="geo-badge">🚫 Блок: ' + escapeHtml(blockedList) + '</span>' +
 '</div>' +
 '<div class="geo-block-actions">' +
 '<a class="geo-btn" href="' + escapeAttr(HOME_URL) + '">🏠 На главную</a>' +
 contactBtn +
 '</div>' +
 '<p class="geo-legal">Страна определена по IP адресу через GeoIP сервис.</p>' +
 '</div>' +
 '</div>';

 document.open();
 document.write(
 "<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Доступ ограничен</title>" +
 css +
 "</head><body>" + html + "</body></html>"
 );
 document.close();
 }

 function getGeo() {
 return fetch("https://ipapi.co/json/", { cache: "no-store" })
 .then(function (r) { return r.json(); })
 .then(function (d) {
 return {
 code: d.country_code ? d.country_code.toUpperCase() : "",
 name: d.country_name || ""
 };
 });
 }

 document.documentElement.style.visibility = "hidden";

 getGeo().then(function (geo) {
 if (BLOCKED.indexOf(geo.code) !== -1) {
 renderBlock(geo.code, geo.name);
 } else {
 showPage();
 }
 }).catch(showPage);

})();
</script>

Как выбрать страны для блокировки и какие коды использовать

Блокировка настраивается через массив BLOCKED. В нем указываются двухбуквенные коды стран по стандарту ISO 3166-1 alpha-2. Примеры: UA, US, DE, PL, RO, FR.

Где взять коды стран.

  • Проще всего открыть список ISO кодов стран в любом справочнике по запросу “ISO 3166-1 alpha-2 country codes”.

  • Также можно ориентироваться на код, который возвращает GeoIP сервис. В нашем случае ipapi.co возвращает поле country_code, и именно его мы сравниваем со списком BLOCKED.

Что именно менять в коде?

Список заблокированных стран

  • Найдите строку: var BLOCKED = ["RU", "BY"];
  • Замените на свои значения, например: var BLOCKED = ["RU", "BY", "KZ"];

Почта поддержки

  • Найдите строку: var SUPPORT_EMAIL = "";
  • Укажите email, если нужна кнопка обращения: var SUPPORT_EMAIL = "support@site.com";

Если оставить пустым, кнопка поддержки не будет показана.

Ссылка на главную

  • Найдите строку: var HOME_URL = "/";
  • Можно заменить на конкретный адрес, например: var HOME_URL = "https://example.com/";

Если нужно блокировать не список стран, а наоборот разрешить только определенные, это тоже делается, просто меняется логика проверки. В таком случае сравниваем не с BLOCKED, а с массивом ALLOWED.

Где и как использовать этот код

Этот вариант предназначен именно для точечного применения.

Он подходит, если нужно:

  • ограничить доступ к одной статье;
  • закрыть лендинг для определенных стран;
  • показать юридическое уведомление вместо контента;
  • не затрагивать остальные страницы сайта.

Если же требуется блокировка всего сайта целиком, правильнее использовать системные инструменты uCoz или внешние прокси сервисы. JavaScript в таком случае не нужен и даже не рекомендуется.

Ограничения решения

Важно понимать границы возможностей.

  • JavaScript можно отключить.
  • VPN и прокси легко меняют страну.
  • Это не защита на уровне сервера.

Зато решение быстро внедряется, не требует ключей, не влияет на остальной сайт и отлично подходит для локальных страниц.

Итог

Для uCoz есть два разных подхода:

  • Системные ограничения подходят, когда нужно закрыть весь сайт.
  • JavaScript решение подходит, когда нужен контроль на уровне отдельных страниц.

Использовать стоит тот вариант, который соответствует задаче, а не пытаться одним инструментом закрыть все сценарии сразу.

Оцените полезность материала!

Лицензия: CC BY-SA 4.0

Автор: Юрий Герук

Похожие материалы:

Комментарии