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: браузер честно попытается переключиться и получит отказ соединения вместо warning.
Проверка, что 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, иначе подгрузится старая версия файла.