Википедия
Ширина незагруженного изображения в Вашем браузере: (определяется...)
Высота незагруженного изображения в Вашем браузере: (определяется...)

Совет: чтобы имитировать блокировку Википедии, используйте файл hosts или просто отключитесь от интернета и нажмите "Перепроверить". Изменения hosts вступают в силу не мгновенно.

Недавно Роскомнадзор предпринял попытку блокировки Википедии. Попытка провалилась, и самое время перейти в контрнаступление. В статье под катом я покажу, что, если пользователь Х зашёл на сайт А, то сайт А может определить, заблокирован ли для пользователя другой сайт Б.

А дальше, по намечающейся традиции, изложение пойдёт в вопросно-ответной форме.



Для чего это вообще нужно?


При обсуждении блокировки Википедии сообщество заметило два обстоятельства, которые весьма выгодны цензуре.

Во-первых, Википедия использует HTTPS и, более того, HSTS. Это означает, что заблокирована энциклопедия может быть только целиком (с точностью до домена), но при этом перенаправить на пресловутую страницу с сообщением о блокировке нельзя. Вместо этого высвечивается сообщение об ошибке установления соединения. Это выглядит как внутренняя проблема Википедии и смягчает недовольство пользователя действиями Роскомнадзора; в то же время для развития правового государства необходима обратная связь.

Во-вторых, даже если пользователи узнают о блокировке, многие из них просто не будут знать, что делать. Вешать перманентную плашку "Если заблокировали Википедию - качайте Tor Browser!" на неравнодушных сайтах как минимум странно; в то же время, оповещение пользователей о блокировке Википедии и способах её обхода необходимо. Решение поставленной проблемы и пытается дать настоящая статья.



Хочу демку!


Пожалуйста!



Как это работает?


Создаётся невидимый блок HTML-кода, содержащий два изображения: одно контрольное - с заведомо несуществующего URL, второе сигнальное - любое изображение с проверяемого сайта. Если их размеры через некоторое время совпадают - значит, изображение с проверяемого сайта не загрузилось, то есть он либо "лежит" настолько, что не может отдавать даже статику, либо заблокирован.



А подробнее?


Изображение в HTML, вставлемое тэгом img, по умолчанию имеет размеры, определяемые самим файлом-картинкой. Изображение, которое загрузить не удалось, тоже имеет какие-то размеры - в разных браузерах разные. Вот они (ширина x высота):

Получить размеры элемента на Javascript можно с помощью свойств элемента .offsetWidth и .offsetHeight

А если вдруг сигнальное изображение по размерам совпадёт с тем, что отобразит браузер при ошибке?


Это достаточно маловероятно, учитывая, что сравниваются и ширина, и высота. Можно запросить два изображения заведомо разных размеров и сравнить их полученные размеры. Если совпадут - загрузка прошла неуспешно. И всё же фавиконы в качестве единственных изображений лучше не дёргать.

А исходники?


На гитхабе под GPLv3.

И как этим всем пользоваться?


Постарался сделать код читабельным, хотя, конечно, это не освобождает меня от приведения примера.

	chasAntidot.testSiteWithImg({
		url: 'https://ru.wikipedia.org/static/images/project-logos/ruwiki.png',	//URL картинки-детектора
		ifBlocked: function(){message('заблокирована');},	//callback, если заблокировано
		ifNotBlocked: function(){message('не заблокирована');},	//callback, если не заблокировано
		time: 3500, //Время ожидания ответа в миллисекундах, по умолчанию 4000
		secondImage: 'https://ru.wikipedia.org/favicon.ico',	//URL второй картинки - необязательно
	});
Никаких дополнительных библиотек типа jQuery не требуется, всё на чистом JS.



Хорошо, я готов информировать своих пользователей о возможной блокировке Википедии! Можно мне готовый код?


Во-первых, в любом случае саму библиотеку лучше скачать к себе на сайт. github.io не застрахован от блокировок.

Во-вторых, для чистого JS возможен, например, такой вариант:

chasAntidot.createBanner(
	'Вероятно, <a href="https://ru.wikipedia.org">Википедия</a> заблокирована. <a href="http://rublacklist.net" target="_blank">Узнайте, что нужно сделать!</a>',
	{
		url: 'https://ru.wikipedia.org/static/images/project-logos/ruwiki.png',
		secondImage: 'https://ru.wikipedia.org/favicon.ico',
	}
);

Это, конечно, работает, но не очень красиво :) Патчи, добавляющие функции создания баннеров с использованием различных библиотек, приветствуются!



А если действительно Википедия упадёт?


На этот случай можно использовать схожий механизм, сравнивая доступность картинки напрямую и через какой-нибудь анонимайзер. Ресурс в таком случае можно считать заблокиованным тогда и только тогда, когда через анонимайзер картинка видна, а напрямую - нет. Правда, анонимайзер тоже может быть заблокирован, и тогда придётся проверять ещё и его доступность - например, запрашивая через него картинку с сайта самого РКН.



Где ещё есть толк от этого в народном хозяйстве?