Ограничить формат файла при использовании? - PullRequest
548 голосов
/ 01 декабря 2010

Я бы хотел ограничить тип файла, который можно выбрать из средства выбора файлов собственной ОС, когда пользователь нажимает кнопку «Обзор» в элементе <input type="file"> в HTML.У меня такое ощущение, что это невозможно, но я бы хотел знать, есть ли решение .Я хотел бы придерживаться исключительно HTML и JavaScript;Нет вспышки, пожалуйста.

Ответы [ 9 ]

905 голосов
/ 17 мая 2014

Строго говоря, ответ: нет .Разработчик не может запретить пользователю выбирать файлы любого типа или расширения в диалоговом окне выбора файлов в собственной операционной системе.Но все же атрибут accept <input type = "file"> может помочь обеспечить фильтр в диалоговом окне выбора файлов ОС.Например,

<!-- (IE 10+, Edge, Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

должен обеспечивать способ фильтрации файлов, отличных от .xls или .xlsx.Хотя страница MDN для элемента input всегда говорила, что она поддерживает это, к моему удивлению, это не работало для меня в Firefox до версии 42. Это работает в IE 10+, Edge и Chrome.

Итак, для поддержки Firefox старше 42 лет вместе с IE 10+, Edge, Chrome и Opera, я думаю, лучше использовать список MIME-типов через запятую:

Поведение

<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

[ Edge : раскрывающийся список фильтров типов файлов показывает типы файлов, упомянутые здесь, но не используется по умолчанию в раскрывающемся списке.Фильтр по умолчанию All files (*).]

Вы также можете использовать звездочки в MIME-типах.Например:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3C рекомендует авторам указать оба MIME-типа и соответствующие расширения в атрибуте accept.Итак, подход best :

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge, Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

JS. То же самое: здесь .

Ссылка: Список MIME-типов ВАЖНО: Использование атрибута accept обеспечивает только способ фильтрации в файлах интересующих типов.Браузеры по-прежнему позволяют пользователям выбирать файлы любого типа.Необходимо выполнить дополнительные (на стороне клиента) проверки (с использованием JavaScript, один из способов будет this ), и определенно типы файлов ДОЛЖНЫ быть проверены на сервере ,используя комбинацию MIME-типа, используя как расширение файла, так и его двоичную подпись ( ASP.NET , PHP , Ruby , Java ).Вы также можете обратиться к этим таблицам для типов файлов и их магических чисел , чтобы выполнить более надежную проверку на стороне сервера.Вот три хорошо читает о загрузке файлов и безопасности.

РЕДАКТИРОВАТЬ: Может быть проверка типа файла с использованиемего двоичная подпись также может быть сделана на стороне клиента с помощью JavaScript (а не просто путем просмотра расширения) с использованием HTML5 File API, но, тем не менее, файл должен быть проверен на сервере, поскольку злонамеренный пользователь все еще сможет загружать файлысделав собственный HTTP-запрос.

188 голосов
/ 01 декабря 2010

Для входного тега есть атрибут accept. Тем не менее, это не надежно в любом случае. Браузеры, скорее всего, воспринимают это как «предложение», то есть пользователь, в зависимости от файлового менеджера, также имеет предварительный выбор, отображающий только нужные типы. Они по-прежнему могут выбрать «все файлы» и загрузить любой файл, который они захотят.

Например:

<form>
    <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

Подробнее в спецификации HTML5

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

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

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

87 голосов
/ 02 декабря 2010

Вы можете использовать событие change для отслеживания того, что выбрал пользователь, и уведомить его в этот момент о том, что файл неприемлем. Он не ограничивает фактический список отображаемых файлов, но он ближе всего подходит для клиентской части, кроме плохо поддерживаемого атрибута accept.

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle

45 голосов
/ 01 декабря 2010

Да, вы правы.Это невозможно с HTML.Пользователь сможет выбрать любой файл, который он / она хочет.

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

Что-то вроде:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

HTML-код:

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>
18 голосов
/ 01 декабря 2010

Технически вы можете указать атрибут accept (альтернативно html5 ) для элемента input, но он не поддерживается должным образом.

9 голосов
/ 31 декабря 2015

Использовать тег input с атрибутом accept

<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

Нажмите здесь, чтобы получить последнюю таблицу совместимости с браузером

Live демо

здесь

Чтобы выбрать только файлы изображений, вы можете использовать это accept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

Live демо здесь

Only gif, jpg and png will be shown, screen grab from Chrome version 44 Будут показаны только gif, jpg и png, скриншот из версии Chrome 44

8 голосов
/ 10 августа 2014

Я знаю, что уже немного поздно.

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}
5 голосов
/ 01 декабря 2010

Вы могли бы сделать это с помощью javascript, но помните, что js - это сторона клиента, поэтому вы фактически будете «предупреждать пользователей», какие типы файлов они могут загружать, если вы хотите ИЗБЕГАТЬ (ограничить или ограничить, как вы сказали) определенный тип файлы, которые вы ДОЛЖНЫ делать на стороне сервера.

Посмотрите этот базовый вариант , если вы хотите начать проверку на стороне сервера. Для всего учебника посетите эту страницу .

Удачи!

2 голосов
/ 10 мая 2014

Как упоминалось в предыдущих ответах, мы не можем ограничивать выбор пользователем файлов только для заданных форматов файлов. Но очень удобно использовать тег accept для атрибута файла в html.

Что касается проверки, мы должны сделать это на стороне сервера. Мы также можем сделать это на стороне клиента в js, но это не надежное решение. Мы должны проверить на стороне сервера.

Для этих требований я действительно предпочитаю Struts2 среду разработки веб-приложений на Java. Благодаря встроенной функции выгрузки файлов загрузка файлов в веб-приложения на базе struts2 становится простой задачей. Просто упомяните форматы файлов, которые мы хотели бы принять в нашем приложении, а все остальное заботится о ядре самой платформы. Вы можете проверить это на официальном сайте стоек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...