Проверьте соответствие атрибутов выбранного файла тегу <input>

0

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

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

> i = document.querySelector('input[type=file]')
<input type=​"file" accept=​"image/​*" name=​"attachment" required>​
> i.accept
"image/*"
> i.files[0].type
"application/x-zip-compressed"
> i.checkValidity()
true

Есть ли простой способ сделать это? Единственное, что я обнаружил, что близко, это jQuery Validate, но это немного сложное решение.

Теги:
validation

1 ответ

4
Лучший ответ

Вы можете просто выполнить тест RegExp - следующий преобразует подстановочный знак в строках типа MIME для соответствия синтаксису RegExp и проверяет его на тип входного файла:

( new RegExp( i.accept.replace( '*', '.\*' ) ) ).test( i.files[ 0 ].type )

Демо здесь.

РЕДАКТИРОВАТЬ:

В конце концов, я нашел способ сделать эту функциональность без изменений с учетом поведения браузера (т.е. Предотвратить отправку недопустимых входов, уведомить пользователя, используя встроенные предупреждения проверки), но я не совсем точно знаю, как работает код, или это хорошая практика (I ' вы спрашивали о чужой части здесь). Однако, похоже, это ведет себя так, как ожидалось, по крайней мере в Chrome 31:

void function enhanceFileInputTypeValidityCheck(){
    var inputPrototype      = document.createElement( 'input' ).constructor.prototype;
    var nativeCheckValidity = inputPrototype.checkValidity;

    function validateFileInputType( input ){
        var MIMEtype = new RegExp( input.accept.replace( '*', '.\*' ) );

        return Array.prototype.every.call( input.files, function passesAcceptedFormat( file ){
            return MIMEtype.test( file.type );
        } );
    }

    function validateInputs(){
        Array.prototype.forEach.call( document.querySelectorAll( 'input, select' ), function callValidation( input ){
            input.checkValidity();
        } );
    }

    inputPrototype.checkValidity = function enhancedCheckValidity(){        
        if( this.type === 'file' &&  this.accept && this.files && this.files.length ){
            if( !validateFileInputType( this ) ){
                this.setCustomValidity( 'Please only submit files of type ' + this.accept );

                return false;
            }
        }

        return nativeCheckValidity.apply( this );
    }

    Array.prototype.forEach.call( [ 'change', 'input' ], function bindValidation( event ){
        document.documentElement.addEventListener( event, validateInputs );
    } );
}();

Демо здесь (попытка отправить с недопустимым типом файла).

  • 0
    Спасибо, я адаптировал это для своего проекта и добавил ответ на твой вопрос. Кроме того, ваша вторая ссылка JSFiddle не работает должным образом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню