检查所选文件是否与& lt; input& gt;上的accept属性匹配标签 [英] Check selected file matches accept attribute on an <input> tag

查看:124
本文介绍了检查所选文件是否与& lt; input& gt;上的accept属性匹配标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望防止用户上传文件,服务器将拒绝页面上包含最少JavaScript的文件,理想情况下,无需添加任何像jQuery这样的繁重依赖项即可纯粹解决这一问题.

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

有没有简单的方法可以做到这一点?我发现唯一接近的是 jQuery Validate ,但这是一个重量级的解决方案

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.

推荐答案

您可以执行RegExp测试-以下内容将MIME类型字符串中的通配符转换为与RegExp语法匹配的内容,并针对输入文件的类型进行测试:

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 )

此处演示.

我最终找到了一种使此功能与本机浏览器验证行为无缝的方法(即,防止提交无效输入,使用本机验证警告通知用户),但是我不确定代码的工作方式或是否是好的做法(我已经在这里问到一些陌生的部分).但是,至少在Chrome 31中,这似乎表现出预期的效果:

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).

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

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