js获取上传文件类型的三种方式及伪文件类型辨别

js获取上传文件类型的三种方式及伪文件类型辨别

文件类型很多,我们常用的方式是通过后缀来辨识文件类型,那么如果文件真实类型与后缀不一致呢,我们怎么才能判别真实的文件类型,识别哪些伪造的文件。我们一个个来说:

一、通过后缀

先获取上传文件的文件名,然后根据文件名截取文件后缀,代码如下:

<!DOCTYPE html>
<html>

<head>

</head>

<body>
    <input type="file" id="fileInput">
    <div id="output"></div>
    <script type="text/javascript">

        
        fileInput.onchange = function() {
            var filename=fileInput.files[0].name;
            
             var suffixname =filename.substr(filename.lastIndexOf(".")).toLowerCase();
              output.innerHTML = suffixname;
            
        };
    </script>
</body>

</html>

二、通过file.type

通过file对象的type属性既可以获取上传文件的类型,类似于image/png这种格式的,代码如下:

<!DOCTYPE html>
<html>

<head>

</head>

<body>
    <input type="file" id="fileInput">
    <div id="output"></div>
    <script type="text/javascript">

        
        fileInput.onchange = function() {
            var filetype=fileInput.files[0].type;
              output.innerHTML = filetype;
          
            
            
        };
    </script>
</body>

</html>

以上两种办法获取上传文件的类型存在一个问题,如果我把别的类型的后缀更换了,那么以上两种办法获取的文件类型无法获取真实的文件类型,例如我把example.doc文件改成了example.png,那么上传后,上面两种方法获取文件类型分别是.png和image/png,但是其实这个文件是doc文档类型的,那么js如何获取文件的真实类型呢,下面我们说第三种,通过二进制读取文件头部字节的方式。

三、通过二进制获取mine type

我们可以通过读取文件的头4个字节结合pattern与mask进行文件签名匹配就可以获取到该文件的真实类型,代码如下:

<!DOCTYPE html>
<html>

<head>

</head>

<body>
    <input type="file" id="fileInput">
    <div id="output"></div>
    <script type="text/javascript">

function loadMime(file, callback) {
   
    //已知文件mine类型标识
    var mimes = [
        {
            mime: 'image/jpeg',
            pattern: [0xFF, 0xD8, 0xFF],
            mask: [0xFF, 0xFF, 0xFF],
        },
        {
            mime: 'image/png',
            pattern: [0x89, 0x50, 0x4E, 0x47],
            mask: [0xFF, 0xFF, 0xFF, 0xFF],
        }
        // 更多扩展的mine标识请看这个 https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern
    ];

    function check(bytes, mime) {
        for (var i = 0, l = mime.mask.length; i < l; ++i) {
            if ((bytes[i] & mime.mask[i]) - mime.pattern[i] !== 0) {
                return false;
            }
        }
        return true;
    }

    var blob = file.slice(0, 4); //读取文件的头部4个字节

  ...

点击查看剩余70%

{{collectdata}}

网友评论0