Как работает интернет

Интернет — глобальная сеть компьютеров, обменивающихся данными по стандартизированным протоколам (TCP/IP), где каждое устройство идентифицируется уникальным адресом (IP).

Зачем нужно

Веб-разработчик работает с сетью каждый день: HTTP-запросы, API, WebSocket, кэширование, безопасность (HTTPS). Без понимания протоколов невозможно отлаживать сетевые проблемы, оптимизировать загрузку и проектировать надёжные системы.

Где используется

  • Веб-приложения (HTTP/HTTPS)
  • REST API и GraphQL
  • Реал-тайм коммуникация (WebSocket)
  • Отправка email (SMTP)
  • Передача файлов (FTP/SFTP)
  • DNS-резолвинг

Предпосылки

Модель TCP/IP

Данные в интернете проходят через стек протоколов — каждый уровень решает свою задачу:

┌─────────────────────────────────────────────┐
│  4. Прикладной (Application)                │
│     HTTP, HTTPS, FTP, SMTP, DNS, WebSocket  │
│     → Данные для приложений                 │
├─────────────────────────────────────────────┤
│  3. Транспортный (Transport)                │
│     TCP, UDP                                │
│     → Надёжная (TCP) или быстрая (UDP)      │
│       доставка между приложениями           │
├─────────────────────────────────────────────┤
│  2. Сетевой (Internet)                      │
│     IP (IPv4, IPv6)                         │
│     → Маршрутизация пакетов между сетями    │
├─────────────────────────────────────────────┤
│  1. Канальный (Link)                        │
│     Ethernet, Wi-Fi                         │
│     → Физическая передача данных            │
└─────────────────────────────────────────────┘

TCP vs UDP

Параметр TCP UDP
Надёжность Гарантирует доставку Не гарантирует
Порядок Сохраняет порядок пакетов Не сохраняет
Скорость Медленнее (handshake) Быстрее
Применение HTTP, email, файлы Видео, игры, DNS

IP-адреса

Каждое устройство в сети имеет уникальный IP-адрес.

IPv4: 192.168.1.1       (4 числа по 0–255, 32 бита)
IPv6: 2001:db8::1       (128 бит, для будущего)

Специальные адреса:

  • 127.0.0.1 (localhost) — ваш собственный компьютер
  • 192.168.x.x — локальная сеть
  • 0.0.0.0 — все интерфейсы

Порт — номер «двери» на устройстве. IP + порт = конкретное приложение.

http://example.com:80    ← порт 80 (HTTP по умолчанию)
https://example.com:443  ← порт 443 (HTTPS по умолчанию)
localhost:3000           ← порт 3000 (dev-сервер)

DNS (Domain Name System)

DNS переводит доменные имена в IP-адреса.

Вы вводите: google.com

1. Браузер проверяет свой кэш
2. ОС проверяет файл hosts и свой кэш
3. Запрос к DNS-резолверу провайдера
4. Резолвер спрашивает корневой DNS-сервер → .com → google.com
5. Получен IP: 142.250.74.46
6. Браузер подключается к этому IP
// В Node.js можно разрешить DNS вручную
const dns = require('dns');

dns.resolve('google.com', (err, addresses) => {
  console.log(addresses); // ['142.250.74.46']
});

// В браузере DNS происходит автоматически
// перед каждым fetch/XHR запросом

HTTP / HTTPS

Структура URL

https://api.example.com:443/users/42?format=json#section1
└─┬──┘ └──────┬───────┘└┬┘└───┬───┘ └────┬────┘ └──┬───┘
протокол    хост       порт  путь    query string  fragment

HTTP-запрос

GET /users/42 HTTP/1.1          ← метод + путь + версия
Host: api.example.com           ← заголовки
Accept: application/json
Authorization: Bearer token123

                                ← пустая строка
                                ← тело (для POST, PUT)

HTTP-ответ

HTTP/1.1 200 OK                 ← статус
Content-Type: application/json  ← заголовки
Cache-Control: max-age=3600

{"id": 42, "name": "Alice"}    ← тело ответа

HTTP-методы

Метод Действие Идемпотентный Тело запроса
GET Получить данные Да Нет
POST Создать ресурс Нет Да
PUT Заменить ресурс Да Да
PATCH Частично обновить Нет Да
DELETE Удалить ресурс Да Нет

Коды ответов

Диапазон Категория Примеры
1xx Информационные 101 Switching Protocols
2xx Успех 200 OK, 201 Created, 204 No Content
3xx Перенаправление 301 Moved, 304 Not Modified
4xx Ошибка клиента 400 Bad Request, 401 Unauthorized, 404 Not Found
5xx Ошибка сервера 500 Internal Error, 502 Bad Gateway, 503 Unavailable

Пример запроса в JavaScript

// Fetch API (браузер и Node 18+)
async function getUser(id) {
  try {
    const response = await fetch(`https://api.example.com/users/${id}`, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
      },
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    const user = await response.json();
    console.log(user); // { id: 42, name: "Alice" }
    return user;
  } catch (error) {
    console.error('Ошибка запроса:', error.message);
  }
}

// POST-запрос
async function createUser(data) {
  const response = await fetch('https://api.example.com/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  });

  return response.json();
}

createUser({ name: 'Bob', email: 'bob@example.com' });

HTTPS и безопасность

HTTPS = HTTP + TLS (шифрование).

HTTP:  данные передаются открытым текстом (можно перехватить)
HTTPS: данные шифруются TLS-сертификатом (нельзя прочитать)

TLS Handshake (упрощённо)

Клиент → Сервер: "Привет, я поддерживаю TLS 1.3"
Сервер → Клиент: "Вот мой сертификат (публичный ключ)"
Клиент: Проверяет сертификат через CA
Клиент → Сервер: Обмен ключами (Diffie-Hellman)
→ Установлен зашифрованный канал
→ Все дальнейшие данные шифруются

Цикл запроса-ответа (Request/Response)

Когда вы открываете веб-страницу, происходит:

1. Ввод URL → DNS → IP-адрес сервера
2. TCP-соединение (3-way handshake: SYN → SYN-ACK → ACK)
3. TLS-handshake (если HTTPS)
4. GET-запрос отправлен серверу
5. Сервер обрабатывает запрос
6. Сервер отправляет HTML-ответ
7. Браузер парсит HTML
8. Браузер обнаруживает CSS, JS, изображения → новые запросы
9. CSS парсится → CSSOM
10. JS выполняется
11. HTML + CSS → рендер страницы
// Наблюдение за сетью в JavaScript
// Performance API показывает тайминги
const entries = performance.getEntriesByType('navigation');
console.log(entries[0]);
// {
//   domainLookupStart: 0,    // начало DNS
//   domainLookupEnd: 5,      // конец DNS
//   connectStart: 5,         // начало TCP
//   connectEnd: 25,          // конец TCP+TLS
//   requestStart: 25,        // отправка запроса
//   responseStart: 125,      // первый байт ответа (TTFB)
//   responseEnd: 200,        // весь ответ получен
//   domContentLoadedEventEnd: 350  // DOM готов
// }

Частые ошибки

  1. Путать HTTP и HTTPS. На HTTP данные видны всем в сети — всегда используйте HTTPS
  2. Не обрабатывать сетевые ошибки. fetch не бросает ошибку на 404/500 — проверяйте response.ok
  3. Игнорировать CORS. Браузер блокирует запросы к другим доменам без соответствующих заголовков
  4. Не учитывать латентность. Сетевой запрос ~50-300 мс — это в 1000 раз медленнее чтения RAM

Практика

  1. Откройте DevTools → Network и перезагрузите страницу. Изучите запросы
  2. Выполните fetch-запрос к публичному API:
    fetch('https://jsonplaceholder.typicode.com/users/1')
      .then(r => r.json())
      .then(console.log);
    
  3. Попробуйте nslookup google.com в терминале — увидите DNS-разрешение

Связанные темы

Ресурсы

  • MDN — An overview of HTTP
  • How DNS Works (howdns.works) — визуальное объяснение
  • HTTP Status Dogs (httpstatusdogs.com) — коды ответов с мемами
  • High Performance Browser Networking (Ilya Grigorik) — бесплатная книга