← Назад к вопросам

Как браузер поймет что видит картинку?

2.0 Middle🔥 131 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как браузер поймет что видит картинку?

Браузер определяет, что перед ним картинка, с помощью нескольких механизмов. Это происходит на разных уровнях: от HTML кода до анализа самого файла.

1. HTML тег <img>

Самый очевидный способ — элемент <img> в HTML:

<!-- Браузер знает, что это картинка, потому что тег img -->
<img src="photo.jpg" alt="My photo" />

<!-- Также работает с source в picture -->
<picture>
  <source srcset="photo.webp" type="image/webp" />
  <source srcset="photo.jpg" type="image/jpeg" />
  <img src="photo.jpg" alt="Photo" />
</picture>

Когда браузер встречает тег <img>:

  1. Видит атрибут src
  2. Загружает файл по этому пути
  3. Анализирует файл (см. пункт 2)
  4. Если это картинка — отображает её

2. MIME type (главный механизм)

При загрузке файла с сервера браузер проверяет заголовок Content-Type:

HTTP Response Headers:
Content-Type: image/jpeg

Браузер видит, что это изображение формата JPEG, и отображает его как картинку.

Основные MIME типы изображений:
image/jpeg       -> .jpg, .jpeg
image/png        -> .png
image/gif        -> .gif
image/webp       -> .webp
image/svg+xml    -> .svg
image/avif       -> .avif
image/x-icon     -> .ico (favicon)

Как сервер определяет MIME type:

1. По расширению файла (.jpg -> image/jpeg)
2. По магическим байтам (файловой сигнатуре)
3. Явно указано в конфиге сервера

3. Файловая сигнатура (Magic Numbers)

Каждый формат изображения имеет уникальную последовательность байтов в начале файла:

Формат      Сигнатура (шестнадцатеричная)    Текст
JPEG         FF D8 FF                         [ÿØÿ]
PNG          89 50 4E 47                      [‰PNG]
GIF87        47 49 46 38 37                   [GIF87]
GIF89        47 49 46 38 39                   [GIF89]
WEBP         52 49 46 46 ... 57 45 42 50    [RIFF...WEBP]
BMP          42 4D                            [BM]

Пример: файл с расширением .jpg может быть проверен:

// JavaScript может проверить сигнатуру
const file = new File(['...'], 'image.jpg');
const reader = new FileReader();

reader.onload = (event) => {
  const array = new Uint8Array(event.target.result);
  
  // Проверяем сигнатуру JPEG
  if (array[0] === 0xFF && array[1] === 0xD8) {
    console.log('Это реально JPEG!');
  }
};

reader.readAsArrayBuffer(file);

4. Размер и разрешение

В метаданных картинки хранится информация о размере:

Dимensions (ширина x высота):
- PNG: IHDR чанк (13 байт)
- JPEG: SOF (Start of Frame) маркер
- GIF: логический дескриптор экрана
- WebP: VP8/VP8L чанк

Браузер читает эту информацию без загрузки всего файла:

// Браузер знает размер до полной загрузки
const img = new Image();

img.onload = () => {
  console.log(`Размер: ${img.width}x${img.height}`);
};

img.src = 'photo.jpg';

5. CSS background-image

Когда браузер парсит CSS, он видит background-image:

.header {
  background-image: url('bg.jpg');
  background-size: cover;
  background-repeat: no-repeat;
}
  1. Браузер видит url() функцию
  2. Загружает файл
  3. Проверяет Content-Type или сигнатуру
  4. Понимает, что это картинка
  5. Применяет как фон элемента

6. Inline изображения (data URLs)

Изображение может быть встроено прямо в код:

<!-- Base64 кодированное изображение -->
<img
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
  alt="1x1 red pixel"
/>

В этом случае браузер:

  1. Видит data:image/... MIME type в URL
  2. Знает, что дальше идёт изображение
  3. Декодирует base64
  4. Отображает как картинку

7. Полный процесс: как браузер анализирует картинку

1. HTML парсинг
   -> <img src="photo.jpg">
   ^
   Браузер видит img тег

2. Отправка запроса
   -> GET /photo.jpg
   ^
   Браузер запрашивает файл

3. Сервер отправляет файл
   -> HTTP 200
   -> Content-Type: image/jpeg
   -> [байты файла]
   ^
   Браузер видит Content-Type

4. Проверка сигнатуры
   -> Первые байты: FF D8 FF
   ^
   Это JPEG (проверка безопасности)

5. Анализ метаданных
   -> IHDR/SOF чанк
   -> Размер: 1920x1080
   -> Цветовое пространство: RGB
   ^
   Браузер готовится отобразить

6. Декодирование и отображение
   -> Распаковка JPEG данных
   -> Рисование в canvas
   -> Отображение в <img>
   ^
   Пользователь видит картинку!

8. Примеры на JavaScript

Проверка типа файла

function checkIfImage(file) {
  // Способ 1: MIME type
  if (!file.type.startsWith('image/')) {
    return false;
  }
  
  // Способ 2: расширение (ненадежно)
  const ext = file.name.split('.').pop().toLowerCase();
  const validExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
  
  return validExts.includes(ext);
}

const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
  if (checkIfImage(e.target.files[0])) {
    console.log('Это картинка!');
  }
});

Проверка сигнатуры

async function getImageDimensions(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    
    reader.onload = (e) => {
      const arr = new Uint8Array(e.target.result);
      
      // Проверяем сигнатуру
      if (arr[0] === 0xFF && arr[1] === 0xD8) {
        console.log('Это JPEG');
      } else if (arr[0] === 0x89 && arr[1] === 0x50) {
        console.log('Это PNG');
      }
      
      // Создаём Image объект для получения размеров
      const url = URL.createObjectURL(file);
      const img = new Image();
      
      img.onload = () => {
        resolve({ width: img.width, height: img.height });
      };
      
      img.onerror = () => reject('Не картинка!');
      img.src = url;
    };
    
    reader.readAsArrayBuffer(file.slice(0, 16)); // Читаем только начало
  });
}

// Использование
const file = document.querySelector('input[type="file"]').files[0];
getImageDimensions(file).then(dims => {
  console.log(`Размер: ${dims.width}x${dims.height}`);
});

Next.js Image компонент

import Image from 'next/image';

export default function Gallery() {
  return (
    <Image
      src="/photo.jpg"       // Next.js проверит что это картинка
      alt="Photo"
      width={400}
      height={300}
      priority // Загрузить сразу
    />
  );
}

// Next.js автоматически:
// 1. Проверит что это картинка (по расширению)
// 2. Оптимизирует для разных экранов
// 3. Загрузит в подходящем формате (WebP если браузер поддерживает)
// 4. Убедится в указанных размерах

Выводы

Браузер определяет картинку несколькими способами:

  1. HTML тег <img> — явное указание
  2. MIME type (Content-Type) — главный механизм
  3. Файловая сигнатура (Magic Numbers) — проверка безопасности
  4. Расширение файла — вспомогательный способ (ненадежный)
  5. Метаданные формата — размер, цветовое пространство
  6. CSS свойства — background-image
  7. data URLs — встроенные картинки

Самый надежный механизм:

  • MIME type от сервера (Content-Type заголовок)
  • Файловая сигнатура (первые байты файла)

Никогда не полагайся только на расширение файла — это самый ненадежный способ, так как файл может быть переименован вручную.