Блокировщик соцсетей, который спасёт вашу продуктивность

В ста­тье про то, как устро­е­ны адре­са в интер­не­те, мы упо­ми­на­ли, что мож­но само­му, без Рос­ком­над­зо­ра, забло­ки­ро­вать себе соц­се­ти. Напри­мер, вам нуж­но напи­сать диплом, сдать про­ект или успеть с зада­чей к дед­лай­ну: тогда вы запре­ща­е­те ком­пью­те­ру захо­дить на опре­де­лён­ные адре­са в интер­не­те и успеш­но сда­ё­те рабо­ту. Для бло­ки­ров­ки исполь­зо­вал­ся файл hosts — в нём хра­нит­ся настрой­ка внут­рен­не­го DNS-сервиса, кото­рый гово­рит ком­пью­те­ру, по каким адре­сам ходить.

Сего­дня мы возь­мём ту же идею с бло­ки­ров­кой через hosts и выве­дем её на новый уро­вень: вме­сто Одно­класс­ни­ков или Фейс­бу­ка у вас появит­ся страница-заглушка. А что­бы было ещё инте­рес­нее, эта стра­ни­ца будет счи­тать, сколь­ко раз вы сего­дня пыта­лись отвлечь­ся от рабо­ты. Повы­сим, так ска­зать, уро­вень осо­знан­но­сти.

Принцип работы

Напом­ним, как обыч­но ведёт себя бра­у­зер:

  1. Вы вво­ди­те адрес в стро­ку бра­у­зе­ра, и теперь ему нуж­но пере­ве­сти адрес из букв в циф­ры — IP-адрес.
  2. Перед тем как отпра­вить запрос на DNS-сервер, бра­у­зер загля­нет в файл hosts — там напи­са­ны основ­ные пра­ви­ла для все­го ком­пью­те­ра.
  3. Если там про­пи­са­на наша соц­сеть и IP-адрес, куда нуж­но отправ­лять запро­сы для этой соц­се­ти, то бра­у­зер сра­зу будет отправ­лять запро­сы туда.
  4. Если мы там напи­шем, что все запро­сы на vk.com отправ­лять на 127.0.0.1, то такие запро­сы не вый­дут за пре­де­лы ком­пью­те­ра и уйдут на этот адрес.
  5. Обыч­но по это­му адре­су нет ника­ких стра­ниц, но с помо­щью про­грам­мы Apache мы ска­жем ком­пью­те­ру, какую стра­ни­цу нуж­но пока­зы­вать, когда есть запрос на этот адрес.
  6. Настро­им сер­вер, поло­жим в него нашу страницу-заглушку. Она будет счи­тать, сколь­ко раз вы попы­та­лись зай­ти в соц­се­ти, кото­рые сами себе закры­ли.

Пер­вые три пунк­та рабо­та­ют и так, там нам делать нече­го. Нач­нём сра­зу с запи­сей в hosts.

Добавляем соцсети в hosts

Если вы забы­ли, как вно­сить новые запи­си в файл hosts — посмот­ри­те в про­шлой ста­тье раз­дел «Как забло­ки­ро­вать себе соц­се­ти с помо­щью hosts». Там есть подроб­ная инструк­ция, как открыть этот файл и доба­вить в него что-то новое.

Мы будем бло­ки­ро­вать такие сай­ты:

Для это­го наш hosts дол­жен выгля­деть так:

Делаем страницу-заглушку со счётчиком

Логи­ка рабо­ты стра­ни­цы такая:

За осно­ву возь­мём наш обыч­ный шаб­лон, в кото­ром будут две важ­ных части — сооб­ще­ние для поль­зо­ва­те­ля и скрипт обра­бот­ки посе­ще­ний.

Нач­нём с сооб­ще­ния, кото­рое мы сде­ла­ем заго­лов­ком в раз­де­ле <body>:

<h1 id="hello">Привет! Вы сегодня 1-й раз хотели зайти в эту соцсеть.</h1>

Доба­вим сти­ли для заго­лов­ка:

h1{
      text-align: center;
      margin: 20;
      font-family: Verdana, Arial, sans-serif;
      font-size: 50px;
    }

Смот­рим, что полу­чи­лось:


Теперь напи­шем скрипт, кото­рый будет счи­тать, сколь­ко раз за сего­дня откры­ва­лась эта стра­ни­ца. Основ­ное, что мы исполь­зу­ем, — localstorage, имен­но там будем хра­нить всю инфор­ма­цию о посе­ще­ни­ях:

    
language: JavaScript
// счётчик количества посещений

var counter = 0;

 

// запоминаем сегодняшнее число в переменную today

var date = new Date();

var today = date.getDate();

 

// если мы загружаем эту страницу вообще первый раз на этом компьютере и в памяти нет сохранённого значения

if (localStorage.getItem('today') == null) {

 

// берём сегодняшнее число и отправляем его в хранилище

today = date.getDate();

localStorage.setItem('today', today);

 

// заводим в хранилище ячейку counter и обнуляем его, потому что посещений ни разу не было до этого

localStorage.setItem('counter', 0);

 

// если в хранилище уже есть информация о прошлом посещении 

} else {

 

// если последнее посещение было не сегодня

if (today != localStorage.getItem('today')) { 

 

//  запоминаем сегодняшнее число и обнуляем счётчик посещений

localStorage.setItem('counter', 0);

localStorage.setItem('today', today);

}

  }

 

// если в счётчике посещений уже что-то есть…

if (localStorage.getItem('counter') !== null) {

 

// берём оттуда число посещений и увеличиваем его на единицу

counter = parseInt(localStorage.getItem('counter'));

counter += 1;

 

// выводим сообщение

document.getElementById('hello').innerHTML = 'Это уже ' + counter + '-я попытка зайти в эту соцсеть за сегодня.';

 

// сохраняем новое значение счётчика

localStorage.setItem('counter', counter);

 

  // если счётчика посещений до сих пор почему-то нет в хранилище… 

  } else {

 

   // отмечаем первое посещение

   counter = 1;

 

   // записываем его в хранилище

   localStorage.setItem('counter', counter);

  };


Ско­пи­ро­вать код
Код ско­пи­ро­ван

Пару раз обнов­ля­ем стра­ни­цу, что­бы убе­дить­ся, что всё рабо­та­ет:


Сохра­ня­ем файл под име­нем index.html — он нам при­го­дит­ся, когда будем настра­и­вать вир­ту­аль­ный сер­вер.

Полный текст страницы

    
language: HTML
<!DOCTYPE html>

<html>

 

<!-- служебная часть -->

<head>

  <!-- заголовок страницы -->

  <title>Иди работать!</title>

 

  <!-- настраиваем служебную информацию для браузеров -->

  <meta charset="utf-8">

  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

 

  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->

  <style type="text/css">

 

    /*параметры заголовка*/

    h1{

      text-align: center;

      margin: 20;

      font-family: Verdana, Arial, sans-serif;

      font-size: 50px;

    }

 

  /*закончили со стилями*/

  </style>

 

<!-- закрываем служебную часть страницы -->

</head>

 

<!-- началось содержимое страницы -->

<body>

 

  <!-- началась видимая часть -->

  

  <!-- заголовок страницы -->

  <h1 id="hello">Привет! Вы сегодня 1-й раз хотели зайти в эту соцсеть.</h1>

 

  <!-- закончилась видимая часть -->

 

  <!-- пишем скрипт, который будет постоянно сохранять наш текст -->

  <script>

    

// счётчик количества посещений

var counter = 0;

 

// запоминаем сегодняшнее число в переменную today

var date = new Date();

var today = date.getDate();

 

// если мы загружаем эту страницу вообще первый раз на этом компьютере и в памяти нет сохранённого значения

if (localStorage.getItem('today') == null) {

 

// берём сегодняшнее число и отправляем его в хранилище

today = date.getDate();

localStorage.setItem('today', today);

 

// заводим в хранилище ячейку counter и обнуляем его, потому что посещений ни разу не было до этого

localStorage.setItem('counter', 0);

 

// если в хранилище уже есть информация о прошлом посещении 

} else {

 

// если последнее посещение было не сегодня

if (today != localStorage.getItem('today')) { 

 

//  запоминаем сегодняшнее число и обнуляем счётчик посещений

localStorage.setItem('counter', 0);

localStorage.setItem('today', today);

}

  }

 

// если в счётчике посещений уже что-то есть…

if (localStorage.getItem('counter') !== null) {

 

// берём оттуда число посещений и увеличиваем его на единицу

counter = parseInt(localStorage.getItem('counter'));

counter += 1;

 

// выводим сообщение

document.getElementById('hello').innerHTML = 'Это уже ' + counter + '-я попытка зайти в эту соцсеть за сегодня.';

 

// сохраняем новое значение счётчика

localStorage.setItem('counter', counter);

 

  // если счётчика посещений до сих пор почему-то нет в хранилище… 

  } else {

 

   // отмечаем первое посещение

   counter = 1;

 

   // записываем его в хранилище

   localStorage.setItem('counter', counter);

 

  };

       

  // закончился скрипт

  </script>

 

<!-- закончилось содержимое страницы -->

</body>

 

<!-- конец всего HTML-документа -->

</html>


Ско­пи­ро­вать код
Код ско­пи­ро­ван

Минутка занудства о протоколах

Если сей­час открыть файл index.html в бра­у­зе­ре, он будет рабо­тать, ника­ких про­блем. Скрипт выпол­ня­ет­ся, заго­ло­вок выво­дит­ся, кра­со­та. Но посмот­ри­те на адрес, по кото­ро­му идёт запрос. Ско­рее все­го, он будет начи­нать­ся со сло­ва file или «Файл». Это зна­чит, что бра­у­зер рабо­та­ет с локаль­ной фай­ло­вой систе­мой, не тро­гая ника­кие интер­не­ты. Рабо­та­ет фай­ло­вый про­то­кол.

А когда мы дела­ем запрос в интер­нет (напри­мер, на vk.com), у нас в адре­се сто­ит пре­фикс http — это озна­ча­ет, что мы сей­час дела­ем http-запрос, то есть запрос по про­то­ко­лу пере­да­чи гипер­тек­ста.

Пора рас­ска­зать, что такое про­то­ко­лы.

Пред­ставь­те, что вы нахо­ди­тесь дома. Вы берё­те с пол­ки кни­гу и чита­е­те её. Вы по умол­ча­нию счи­та­е­те, что все кни­ги в доме чистые, поэто­му после про­чте­ния вы не буде­те мыть руки.

Теперь вы берё­те кни­гу и идё­те в парк. Домой воз­вра­ща­е­тесь в трол­лей­бу­се. Вы зашли домой с ули­цы и пер­вым делом мое­те руки — пото­му что недав­но дер­жа­лись за гряз­ные поруч­ни. Вы точ­но так же чита­ли кни­гу, но из-за осо­бен­но­стей транс­пор­та теперь ведё­те себя по-другому.

Как вы ведё­те себя в этих двух ситу­а­ци­ях — это про­то­кол. Про­то­кол — это опре­де­лён­ные пра­ви­ла, по кото­рым вы вза­и­мо­дей­ству­е­те с окру­жа­ю­щим миром: после транс­пор­та мыть руки, на поро­ге сни­мать обувь, на рабо­те здо­ро­вать­ся и так далее. У ком­пью­те­ров то же самое: есть про­то­ко­лы для веб-страниц (http), пере­да­чи фай­лов (ftp), рабо­ты с поч­той (imap) и так далее.

Так вот: фай­ло­вый про­то­кол, по кото­ро­му вы откры­ва­е­те фай­лы с дис­ка, — это не то же самое, что http-протокол, по кото­ро­му идут запро­сы из бра­у­зе­ра.

За испол­не­ние запро­сов по про­то­ко­лу file отве­ча­ет ваша опе­ра­ци­он­ная систе­ма. А за испол­не­ние http-запросов — спе­ци­аль­ная про­грам­ма, кото­рая назы­ва­ет­ся веб-сервером. Когда в ком­пью­тер при­ле­та­ет http-запрос, он ищет в памя­ти запу­щен­ный веб-сервер и кида­ет запрос в него. Раз­би­рай­ся, мол.

Сей­час на вашем ком­пью­те­ре не рабо­та­ет ника­ко­го веб-сервера. Если вы набе­рё­те в бра­у­зе­ре http://127.0.0.1, вы полу­чи­те ошиб­ку, пото­му что у вас в памя­ти нет про­грам­мы, кото­рая обра­ба­ты­ва­ет http-запросы. Адрес дей­стви­те­лен, но ответ­ствен­но­го по http нет, поэто­му и ошиб­ка.

Настраиваем Апач

Нам нуж­но, что­бы меж­ду бра­у­зе­ром и ком­пью­те­ром про­изо­шёл такой диа­лог:

Бра­у­зер: Алло, алло! Это 127.0.0.1?
Опе­ра­ци­он­ная систе­ма: Вам чего?
Бра­у­зер: У меня http-запрос.
Опе­ра­ци­он­ная систе­ма: ожи­дай­те, пере­во­жу вас на http-сервер.
Http-сервер: У аппа­ра­та. Дик­туй­те ваш запрос.
Бра­у­зер: Запра­ши­ваю стра­ни­цу по адре­су vk.com, про­то­кол http.
Http-сервер: Жди­те, испол­няю…

Для это­го диа­ло­га в памя­ти наше­го ком­пью­те­ра долж­на появить­ся программа-сервер, кото­рая откли­ка­ет­ся на http-запросы. Сер­вер­ных про­грамм мно­го, мы исполь­зу­ем самую рас­про­стра­нён­ную — Apache, она же Апач. Как индей­ское пле­мя.

Поль­зо­ва­те­лям MacOS повез­ло — Апач уже встро­ен в опе­ра­ци­он­ную систе­му и готов к настрой­ке. Для Windows его при­дёт­ся ста­вить отдель­но.

Раз­ра­бот­чи­ки Апа­ча исхо­дят из того, что у вас доста­точ­но ква­ли­фи­ка­ции для само­сто­я­тель­ной сбор­ки про­грам­мы из исход­но­го кода. Нам при­ят­но, что о нас так дума­ют, но мы сде­ла­ем про­ще — возь­мём офи­ци­аль­ную сбор­ку XAMPP от парт­нё­ров Apache Software Foundation. В ком­плек­те с сер­ве­ром идёт база дан­ных и под­держ­ка PHP и Perl. Сей­час они нам не нуж­ны, но при­го­дят­ся в буду­щих про­ек­тах. Ска­чай­те и уста­но­ви­те её как обыч­ную про­грам­му.

После уста­нов­ки попа­да­ем в панель управ­ле­ния все­ми моду­ля­ми и нажи­ма­ем Start напро­тив Апа­ча, что­бы убе­дить­ся, что всё рабо­та­ет как нуж­но:

Теперь, когда мы набе­рём в стро­ке бра­у­зе­ра localhost и нажмём кла­ви­шу вво­да, то уви­дим такую стра­ни­цу. Она озна­ча­ет, что апач уста­нов­лен и рабо­та­ет пра­виль­но:

Если у вас Макин­тош, то вме­сто ска­чи­ва­ния и уста­нов­ки доста­точ­но в тер­ми­на­ле напи­сать коман­ду:

sudo apachectl start

После это­го по адре­су localhost будет стра­ни­ца с тек­стом It works, кото­рая гово­рит нам о том, что всё рабо­та­ет.

Указываем путь к нашей странице

Послед­нее, что нам оста­лось сде­лать, — научить Апач пока­зы­вать нашу стра­ни­цу вме­сто сво­ей заглуш­ки.

Для это­го нам нуж­но най­ти путь, по кото­ро­му Апач ищет фай­лы для отоб­ра­же­ния, и поло­жить в эту же пап­ку нашу стра­ни­цу. Что­бы най­ти путь, нажи­ма­ем кноп­ку Config напро­тив Апа­ча и выби­ра­ем первую строч­ку — httpd.conf:

Появ­ля­ет­ся окно редак­то­ра, в кото­ром открыл­ся файл с настрой­ка­ми наше­го сер­ве­ра. Нуж­но най­ти строч­ку DocumentRoot, кото­рая пока­жет нам, куда Апач обра­ща­ет­ся за веб-страницами:

Мы видим, что Апач обра­ща­ет­ся к пап­ке C:/xampp/htdocs. Это зна­чит, что про­ще все­го будет поло­жить наш файл index.html в эту пап­ку, а всё осталь­ное содер­жи­мое пап­ки — уда­лить, пото­му что оно нам не нуж­но.

Мы всё сде­ла­ли, теперь мож­но спо­кой­но рабо­тать — как толь­ко мы попро­бу­ем несколь­ко раз зай­ти в Одно­класс­ни­ки, уви­дим такое:


К сожа­ле­нию, с фейс­бу­ком так не полу­чит­ся, и сайт пока­жет нам такое сооб­ще­ние:


Всё дело в том, что совре­мен­ные бра­у­зе­ры исполь­зу­ют тех­но­ло­гию HSTS, кото­рая отсле­жи­ва­ет, всё ли в поряд­ке с кана­лом свя­зи от ком­пью­те­ра до сай­та. Если HSTS видит, что что-то с кана­лом или настрой­ка­ми сети не так, то в целях без­опас­но­сти он бло­ки­ру­ет такое соеди­не­ние и выво­дит сооб­ще­ние об ошиб­ке. Обой­ти штат­ны­ми сред­ства­ми это нель­зя — сай­ты типа фейс­бу­ка или гуг­ла уже впи­са­ны в HSTS-настройки бра­у­зе­ра и уда­лить их отту­да не полу­чит­ся.

Как сде­лать так, что­бы это не меша­ло нам пока­зы­вать стра­ни­цу и филь­тро­вать тра­фик силь­нее, чем сей­час, — рас­ска­жем в отдель­ной ста­тье.