在< input>检查所选文件匹配接受属性标签 [英] Check selected file matches accept attribute on an <input> tag

查看:104
本文介绍了在< input>检查所选文件匹配接受属性标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望防止用户上传文件,服务器会从页面上以最少的JavaScript来拒绝文件,理想情况下不需要像jQuery那样增加任何重要的依赖关系,纯粹是为了解决这个问题。



因为我不是针对传统用户,所以我使用浏览器的表单验证系统来检查用户是否选择了一个有效的文件,但它似乎只关心用户是否选择文件而不管类型。

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

有没有简单的方法来做到这一点?我唯一发现的就是 jQuery Validate ,但它有点重量级的解决方案

解决方案

您可以执行RegExp测试 - 下面的代码转换MIME类型字符串中的通配符以匹配RegExp语法,这对输入文件的类型:

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

演示这里



编辑:

<我最终找到了一种方法,使本功能与本地浏览器验证行为无缝对接(即防止提交无效输入,通知用户使用本地验证警告),但我不确定代码是如何工作的或者它是否是好的做法( 我已经问过这里的陌生人部分)。但是,这至少在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('*','.\ *'));

返回Array.prototype.every.call(input.files,函数passesAcceptedFormat(file){
return MIMEtype.test(file.type);
});


函数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。文件&& this.files.length){
if(!validateFileInputType(this)){
this.setCustomValidity('请只提交'+ this.accept'类型的文件);

返回false;
}
}

返回nativeCheckValidity.apply(this);


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

演示此处(尝试使用无效的文件类型提交)。


I wish to prevent the user from uploading a file the server will reject from a page with minimal JavaScript on it, ideally without adding any heavy dependencies like jQuery purely to solve this one problem.

Since I'm not targeting legacy users, I trued using the browser's form validation system to check if the user has selected a valid file, however it only seems to care if the user selects a file regardless of type.

> 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

Is there a simple way of doing this? The only thing that I have found that comes close is jQuery Validate, but it's a bit of a heavyweight solution.

解决方案

You could just perform a RegExp test — the following converts the wildcard in MIME type strings to match RegExp syntax, and tests that against the input file's type:

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

Demo here.

EDIT:

I eventually found a way to make this functionality seamless with native browser validation behaviour (ie prevent submission for invalid inputs, notify user using native validation warnings), but I'm not exactly sure how the code works or whether it's good practice (I've asked about the stranger parts here). However, this appears to behave as expected, at least in 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 );
    } );
}();

Demo here (attempt to submit with an invalid file type).

这篇关于在&lt; input&gt;检查所选文件匹配接受属性标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆