Yesterday

Три разных проверки за кнопкой «Выбрать файл»

Поле загрузки принимает изображения. В диалоге выбора доступны PNG, а после выбора интерфейс показывает имя cover.png. В этот момент легко объединить три разных события: браузер помог выбрать файл, клиент прочитал его свойства, сервер принял содержимое. Между ними ещё нужны явные правила.

Материал подготовлен с AI-помощью. Пример ниже выполнен локально в Node.js на синтетическом тексте. Он проверяет поведение объектов File; диалог браузера, загрузка по сети и обработка изображения в этом запуске не проверялись.

Что делает диалог выбора

Атрибут accept="image/png,.png" у input type="file" задаёт подсказку о нужных типах. MDN прямо отделяет её от проверки содержимого: во многих диалогах пользователь может переключить фильтр и выбрать другой файл. Поэтому наличие accept в разметке не подтверждает выполнение требований к загрузке. Источник: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept

Такая подсказка всё равно полезна: человеку проще найти подходящий файл. Рядом стоит назвать допустимые форматы и ограничения размера, которые действительно применяет продукт. Текст «Выберите PNG» описывает ожидаемое действие. Сообщение «Файл проверен» уже требует отдельного основания, а не только подходящего расширения в имени.

Имя и MIME описывают разные свойства

У File есть имя и свойство type, унаследованное от Blob. По документации MDN, тип может остаться пустой строкой; браузерное определение может зависеть от расширения и конфигурации клиента. MDN не рекомендует использовать это свойство как единственный способ валидации. Источник: https://developer.mozilla.org/en-US/docs/Web/API/Blob/type

В конструкторе File значение type можно передать явно. Для наглядной проверки достаточно обычной строки, без настоящей картинки и без обращения к серверу. Конструктор принимает содержимое, имя и параметры как разные аргументы. Описание API: https://developer.mozilla.org/en-US/docs/Web/API/File/File

const file = new File(['учебный текст'], 'cover.png', {
  type: 'image/png'
});
console.log(file.name);         // cover.png
console.log(file.type);         // image/png
console.log(await file.text()); // учебный текст

Локальный запуск вывел cover.png, image/png и исходный учебный текст. Дополнительная проверка создала из той же строки объект note.txt с типом text/plain. Их байтовое содержимое совпало. Третий объект, созданный без параметра type, вернул пустую строку типа и сохранил тот же текст. Восемь утверждений завершились успешно.

Из этого следует узкий вывод: в проверенном конструкторе метаданные не доказывают соответствие содержимого выбранному формату. Этот пример не оценивает качество PNG-декодера и не показывает обход конкретного сервиса. Он помогает увидеть, почему проверке file.type === "image/png" нельзя приписывать работу, которую она не выполняла.

Разделить ответственность в задании

Клиентская часть может заранее объяснить ограничения и показать понятную причину отказа по тем свойствам, которые она действительно проверила. Пустой type означает, что тип не определён, а не автоматически «подходящий файл». Поведение для такого случая следует согласовать отдельно и проверить в интерфейсе.

На стороне сервера требуется собственное правило приёма: разрешённые форматы, ограничения ресурсов и подходящая проверка содержимого. Способ проверки зависит от дальнейшей обработки файла. Один заголовок MIME, расширение или короткая сигнатура не описывают всю пригодность документа. Эту задачу нужно определить и проверить отдельно от фильтра диалога.

В приёмочный сценарий полезно включить подходящий файл, неподходящее содержимое под знакомым именем, пустой MIME и превышение установленного размера. Результат каждого случая должен объяснять, какая сторона принимает решение и что видит человек. Синтетические объекты удобны для части таких проверок; работу реального выбора и серверной обработки нужно проверять своими сценариями.

Так в задании для разработчика или AI-ассистента появляются три проверяемых результата: подсказка при выборе, ранняя обратная связь клиента и самостоятельное решение сервера. Это помогает обсуждать конкретное поведение загрузки вместо общей отметки «валидация добавлена».

Олжас Азирали, разработчик приложений из Астаны, основатель AZIRAL с 2019 года.