Как сделать input type = file Должен принимать только pdf и xls


102

я использовал <input type= "file" name="Upload" >

Теперь я хотел бы ограничить это, приняв только файлы .pdf и .xls.

Когда я нажимаю кнопку отправки, он должен это подтвердить.

И когда я нажимаю файлы (PDF / XLS) на веб-странице, они должны автоматически открываться.

Может ли кто-нибудь привести несколько примеров для этого?

Ответы:


179

Вы можете сделать это, используя атрибут acceptи добавив к нему разрешенные типы mime. Но не все браузеры соблюдают этот атрибут, и его можно легко удалить с помощью какого-нибудь инспектора кода. Так что в любом случае вам нужно проверить тип файла на стороне сервера (ваш второй вопрос).

Пример:

<input type="file" name="upload" accept="application/pdf,application/vnd.ms-excel" />

На ваш третий вопрос «И когда я нажимаю на файлы (PDF / XLS) на веб-странице, они должны открываться автоматически»:

Вы не можете этого добиться. Способ открытия PDF или XLS на клиентском компьютере устанавливается пользователем.


Привет, Feela. Когда я загружу файлы, они будут храниться на сервере. Я слышал, что с помощью функций javascript можно открывать файлы .pdf и .xls, щелкая файлы в браузере ...
Маникандан,

вот и все ! Обе стороны клиента и сервера объяснили. Отличный ответ

3
если вы перечислите все файлы в поле выбора. вы все равно можете загрузить любой файл.
rüff0


14

К сожалению, во время выбора нет гарантированного способа сделать это.

Некоторые браузеры поддерживают acceptатрибут для inputтегов. Это хорошее начало, но нельзя полностью полагаться на него.

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

Вы можете использовать cfinputи запустить проверку, чтобы проверить расширение файла при отправке, но не mime-тип. Это лучше, но все же не надежно. Файлы в OSX часто не имеют расширений, иначе пользователи могут злонамеренно пометить типы файлов.

ColdFusion cffileможет проверить mime-тип, используя contentTypeсвойство result ( cffile.contentType), но это можно сделать только после загрузки. Это ваш лучший выбор, но он все же не на 100% безопасен, так как mime-типы могут ошибаться.


3
Пожалуйста, никогда не проверяйте файл на основе расширения. А как насчет исполняемого файла с именем lolcat.jpg?
Feela

1
Я думаю, что phantom42 пытается сказать здесь, что вы должны проверить расширение и тип MIME на сервере. acceptАтрибут на inputметке могут быть добавлены , но не 100% эффективным.
Крис Питерс

Согласен на 100%. На него нельзя положиться, но я считаю его хорошей первой линией защиты в сочетании с cffile.contenttype.
Joe C

Привет, Phantom. Как вы сказали, этот прием работает только в Chrome, а не в IE. Есть ли другой способ сделать это, который будет поддерживаться всеми браузерами
Manikandan

К сожалению нет; вот почему я сказал, что на него нельзя полагаться и его следует использовать вместе с другими методами, если вы вообще его используете.
Joe C

4

Вы можете использовать JavaScript. Учтите, что большая проблема при выполнении этого с помощью JavaScript - сбросить входной файл. Что ж, это ограничивается только JPG (для PDF вам нужно будет изменить тип пантомимы и магическое число ):

<form id="form-id">
  <input type="file" id="input-id" accept="image/jpeg"/>
</form>

<script type="text/javascript">
    $(function(){
        $("#input-id").on('change', function(event) {
            var file = event.target.files[0];
            if(file.size>=2*1024*1024) {
                alert("JPG images of maximum 2MB");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            }

            if(!file.type.match('image/jp.*')) {
                alert("only JPG images");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            }

            var fileReader = new FileReader();
            fileReader.onload = function(e) {
                var int32View = new Uint8Array(e.target.result);
                //verify the magic number
                // for JPG is 0xFF 0xD8 0xFF 0xE0 (see https://en.wikipedia.org/wiki/List_of_file_signatures)
                if(int32View.length>4 && int32View[0]==0xFF && int32View[1]==0xD8 && int32View[2]==0xFF && int32View[3]==0xE0) {
                    alert("ok!");
                } else {
                    alert("only valid JPG images");
                    $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                    return;
                }
            };
            fileReader.readAsArrayBuffer(file);
        });
    });
</script>

Учтите, что это было протестировано на последних версиях Firefox и Chrome, а также на IExplore 10.

Полный список типов пантомимы см. В Википедии .

Полный список магических чисел см. В Википедии .


4

Вы можете попробовать следующий способ

<input type= "file" name="Upload" accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">

ИЛИ (в asp.net mvc)

@Html.TextBoxFor(x => x.FileName, new { @id = "doc", @type = "file", @accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" })

2

Я бы отфильтровал серверную часть файлов, потому что в Firefox есть инструменты, такие как Live HTTP Headers, которые позволяют загружать любой файл, включая оболочку. Люди могут взломать ваш сайт. Сделайте это на сервере, на всякий случай.


Это совершенно верно! Пожалуйста, не игнорируйте этот совет
Родни Сальседо,

1

Хотя этот конкретный пример предназначен для загрузки нескольких файлов, он дает общую необходимую информацию:

https://developer.mozilla.org/en-US/docs/DOM/File.type

Что касается действий с файлом при / download /, это не вопрос Javascript, а скорее конфигурация сервера. Если у пользователя не установлено что-то для открытия файлов PDF или XLS, его единственный выбор - загрузить их.


0

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

<script type="text/JavaScript">
<!-- Begin
function TestFileType( fileName, fileTypes ) {
if (!fileName) return;

dots = fileName.split(".")
//get the part AFTER the LAST period.
fileType = "." + dots[dots.length-1];

return (fileTypes.join(".").indexOf(fileType) != -1) ?
alert('That file is OK!') : 
alert("Please only upload files that end in types: \n\n" + (fileTypes.join(" .")) + "\n\nPlease select a new file and try again.");
}
// -->
</script>

Затем вы можете вызвать функцию из события, такого как onClick вышеуказанной кнопки, что выглядит так:

onClick = "TestFileType (this.form.uploadfile.value, ['gif', 'jpg', 'png', 'jpeg'])»;

Вы можете изменить это на: PDFиXLS

Вы можете увидеть, как это реализовано здесь: Демо


Спасибо Вишал Сутхар. Думаю, эта логика, несомненно, поможет мне двигаться вперед.
Manikandan

С удовольствием .. Это обязательно поможет, но все равно нет голосов за .. ?? @ Manikandan
Vishal Suthar

Тем не менее у меня есть еще одно сомнение. Я попытался ограничить файлы (только PDF и Xls.xlsx) в input type = file. Но он отлично работает в Google Chrome .. Но я не могу сделать это в IE. Есть ли какое-нибудь решение, чтобы ограничить файлы в IE? Если да, пожалуйста, заставьте меня идти правильным путем.
Manikandan

Я только что проверил ( codestore.net/store.nsf/unid/DOMM-4Q8H9E ) в IE, и он отлично работает .. @ Manikandan
Vishal Suthar

По сравнению с acceptатрибутом -attribute, этот метод не сужает содержимое папки до выбранных типов файлов при выборе файла на локальном компьютере.
Feela

0

Попробуй это:-

              <MyTextField
                id="originalFileName"
                type="file"
                inputProps={{ accept: '.xlsx, .xls, .pdf' }}
                required
                label="Document"
                name="originalFileName"
                onChange={e => this.handleFileRead(e)}
                size="small"
                variant="standard"
              />
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.