Mixed content виникає, коли HTTPS-сторінка завантажує ресурси (картинки, скрипти, стилі) по HTTP. Браузер вважає це небезпечним і блокує або попереджає користувача.
Типи mixed content
| Тип | Що включає | Дія браузера |
|---|---|---|
| Active Mixed Content | JS, CSS, iframes | Блокує автоматично |
| Passive Mixed Content | Картинки, аудіо, відео | Показує попередження |
Як знайти mixed content
Chrome DevTools
F12 → Console
Шукайте: "Mixed Content: The page ... was loaded over HTTPS"
Або: "blocked:mixed-content" у Network
Онлайн-інструменти
- Why No Padlock — whynopadlock.com
- SSL Checker — ssllabs.com
Виправлення в WordPress
Метод 1: Плагін Really Simple SSL
Встановіть плагін Really Simple SSL — він автоматично замінює HTTP на HTTPS у контенті та налаштуваннях.
Метод 2: wp-config.php
define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS'] = 'on';
Метод 3: WP-CLI
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# Переконайтеся, що все правильно, потім:
wp search-replace 'http://example.com' 'https://example.com' --all-tables
Виправлення через .htaccess
# Редиректити весь HTTP на HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Заголовок Upgrade-Insecure-Requests
Header always set Content-Security-Policy "upgrade-insecure-requests"
upgrade-insecure-requests — найшвидший спосіб виправити passive mixed content без зміни контенту.Розбір повідомлень про mixed content
Точний текст у консолі браузера чи в PHP-журналі підказує, що саме зламано і чому.
Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure image 'http://...'. This content should also be served over HTTPS.— passive content: браузер завантажить картинку, але покаже попередження і зніме зелений замок.Mixed Content: ... requested an insecure script '...'. This request has been blocked; the content must be served over HTTPS.— active content: скрипт не завантажиться взагалі, сторінка може зламатися візуально чи функціонально.- Статус
(blocked:mixed-content)у колонці Status вкладки Network — запит заблоковано ще до відправлення, на відміну від звичайної помилки сервера. Notice: unserialize(): Error at offset 61 of 89 bytes in ...— типовий симптом після ручногоUPDATE ... REPLACE(...)по базі WordPress: пряма заміна змінює довжину рядка всередині серіалізованих даних, а PHP зберігає довжину в самому значенні, тому розпакування ламається.- У адресному рядку Chrome замість замка — напис «Not Secure» з текстом «Your connection to this site is not fully secure» у спадному вікні: браузер уже бачить хоча б один небезпечний ресурс на сторінці.
Способи виправлення: що коли застосовувати
| Спосіб | Коли застосовувати | Обмеження | Відкат |
|---|---|---|---|
| Плагін Really Simple SSL | Потрібен швидкий фікс на живому сайті без доступу до БД | Переписує вивід на льоту, не виправляє посилання в самій базі | Вимкнення плагіна повертає http-посилання на екран |
| Константи в wp-config.php | Адмінка чи логін генерують http-посилання через проксі чи CDN перед сайтом | Не чіпає посилання в контенті постів і віджетів | Безпечно, це просто PHP-константи |
| wp search-replace | Потрібно постійно виправити посилання в контенті, метаданих і налаштуваннях | Вимагає резервної копії БД перед запуском | Зміни в БД, спочатку перевіряйте прапорцем --dry-run |
| Ручний SQL REPLACE | Не рекомендується для WordPress | Ламає серіалізовані дані, звідси помилка unserialize | Відкат важкий, лише з резервної копії |
Коли ці способи не допоможуть
- Якщо перед сайтом стоїть CDN чи зворотний проксі, який сам звертається до бекенду по HTTP — mixed content створює проксі, а не WordPress, і виправляти потрібно заголовок
X-Forwarded-Protoта налаштування самого проксі. - Вбудований сторонній віджет — наприклад iframe з домену, який ще не видав собі HTTPS-сертифікат — сайт виправити не може, доки сторонній сервіс сам не перейде на HTTPS.
- Правила з
.htaccessпрацюють лише на Apache; на Nginx-бекенді той самий редирект потрібно прописувати в блоціserver {}із синтаксисом Nginx, .htaccess там узагалі не читається. upgrade-insecure-requestsне допоможе, якщо ресурс у принципі недоступний по HTTPS: браузер чесно спробує перемкнутися і отримає відмову зʼєднання замість попередження.
Перевірка, що mixed content справді зник
# Знайти посилання http, що залишились у базі, без внесення змін
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# Перевірити, що сервер віддає потрібні security-заголовки
curl -I https://example.com | grep -i content-security-policy
Після виправлення відкрийте сторінку в приватному вікні (щоб виключити кеш), відкрийте DevTools → Console — рядків із текстом Mixed Content бути не повинно, а замок в адресному рядку має бути закритим, без попереджень.
Часті питання
Як виправити mixed content на сайті, який не побудований на WordPress?
Принцип виправлення однаковий незалежно від рушія: потрібно знайти всі абсолютні посилання на ресурси за протоколом без шифрування і замінити їх на захищений протокол або на відносний шлях без протоколу взагалі. Різниця лише в інструменті пошуку і заміни — замість спеціалізованого плагіна для своєї платформи правки вносять прямо в шаблони, конфігурацію збірки фронтенду чи через глобальний пошук у вихідному коді проєкту.
Чи можна тимчасово дозволити браузеру завантажувати незахищений контент, щоб не блокувати роботу, поки шукається причина?
Дозволити завантаження незахищеного вмісту можна прямо в налаштуваннях конкретного браузера на час однієї вкладки — це знімає блокування лише локально у вас і жодним чином не виправляє сайт для решти відвідувачів. Такий режим зручний винятково для діагностики, щоб побачити, як сторінка виглядає без блокування скриптів, і зрозуміти, який саме ресурс заважає, а не як постійне рішення проблеми.
Чи впливає mixed content на позиції сайту в пошуковій видачі?
Прямого штрафу за сам факт змішаного вмісту пошукові системи не накладають, проте попередження про незахищене з'єднання знижує довіру відвідувачів і погіршує поведінкові показники — зростання відмов і коротший час на сторінці з боку аудиторії пошуковики враховують під час ранжування опосередковано. Крім того, заблоковані скрипти і стилі можуть ламати верстку чи функціональність, що теж впливає на сприйняття сторінки алгоритмом.
Що робити, якщо HTTP-посилання сховані всередині CSS, а не в HTML чи базі даних?
Посилання всередині CSS-файлів, зазначені в правилі url() для фонових зображень чи шрифтів, потрібно шукати окремо від вмісту бази даних — такі файли зазвичай лежать статично на сервері і не зачіпаються автозаміною посилань у постах. Їх правлять вручну або масовим пошуком по файлах теми і зібраних стилях, а після зміни потрібно скинути кеш браузера і CDN, інакше підвантажуватиметься стара версія файлу.