首页 > 其他分享 >js判断文件类型详解

js判断文件类型详解

时间:2023-12-11 15:14:36浏览次数:35  
标签:function 文件 const 后缀 js return 详解 file 文件类型

js判断文件类型详解

通过file的type属性判断

<input type="file" onchange="onchangecb(this)" />
<script>
    function onchangecb(e) {
        const file = e.files[0];
        console.log(file.type);
    }
</script>

htmlinput标签,就是根据选择文件的后缀来生成一个File对象。

像下面的几种文件:

txt文件:
在这里插入图片描述

jpg文件:
在这里插入图片描述

mp4文件:

在这里插入图片描述

使用文件后缀来判断

function onchangecb(e) {
    const file = e.files[0];
    //获取最后一个.的位置
    const index = file.name.lastIndexOf('.');
    //获取后缀
    const ext = file.name.substr(index + 1);
    console.log(ext);
}

在得到文件后缀名后,根据后缀即可判断文件的类型(文件格式)。比如需要判断一个文件是否是图片格式,首先定义一个判断函数:

function isImage(ext) {
    return (
        ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff'].indexOf(
            ext.toLowerCase()
        ) !== -1
    );
}

虽然可以直接通过对象的type属性或者文件后缀来获取文件类型,但是如果强行修改文件后缀,同样可以将其他类型的文件上传至服务器,或者文件压根就没有后缀,那又要怎么判断呢?因此前端需要使用一个更加合理的方式。

根据二进制流及文件头来判断

虽然文件后缀可以手动改,因此可以直接通过读取文件的二进制来判断。

通常来说固定类型的文件头都是相同的,比如说jpeg的文件头是FF D8 FF E0

这里提供一些常用的文件头:

const fileMap = {
    JPEG: 'FF D8 FF E0',
    JPG: 'FF D8 FF E1',
    PNG: '89 50 4E 47',
    GIF: '47 49 46 38',
    TIFF: '49 49 2A 00',
    BMP: '42 4D',
    DWG: '41 43 31 30',
    PSD: '38 42 50 53',
    RTF: '7B 5C 72 74 66',
    XML: '3C 3F 78 6D 6C',
    HTML: '68 74 6D 6C 3E',
    EML: '44 65 6C 69 76 65 72 79 2D 64 61 74 65 3A',
    DBX: 'CF AD 12 FE C5 FD 74 6F',
    PST: '21 42 44 4E',
    XLS: 'D0 CF 11 E0',
    DOC: 'D0 CF 11 E0',
    MDB: '53 74 61 6E 64 61 72 64 20 4A',
    WPD: 'FF 57 50 43',
    PDF: '25 50 44 46 2D 31 2E',
    QDF: 'AC 9E BD 8F',
    PWL: 'E3 82 85 96',
    ZIP: '50 4B 03 04',
    RAR: '52 61 72 21',
    WAV: '57 41 56 45',
    AVI: '41 56 49 20',
    RAM: '2E 72 61 FD',
    RM: '2E 52 4D 46',
    MPG: '00 00 01 BA',
    MPG: '00 00 01 B3',
    MOV: '6D 6F 6F 76',
    ASF: '30 26 B2 75 8E 66 CF 11',
    MID: '4D 54 68 64',
    MP3: '49 44 33',
};

通过onchange方法获取到选择的文件后,使用FileReader读取文件的二进制,之后判断二进制的前几位是否跟符合相应类型文件的文件头。

以下是一些使用文件头来判断文件类型的简单代码

// 判断文件后缀与该文件内容是否相同类型
async function isSameFileType(file) {
    const suffix = getFileSuffix(file.name).toUpperCase();
    const fileBlobString = await blobToString(file.slice(0, 14));
    // 如果文件类型中没有该类型,默认为false
    if (!(suffix in fileMap)) {
        return false;
    }

    return fileBlobString.includes(fileMap[suffix]);
}

async function blobToString(blob) {
    return new Promise((resolve) => {
        const reader = new FileReader();
        reader.onload = function () {
            const ret = reader.result
                .split('') // 分隔开
                .map((v) => v.charCodeAt()) // 循环返回指定位置的字符的 Unicode 编码
                .map((v) => v.toString(16).toUpperCase()) // 返回十六进制格式
                .map((v) => v.padStart(2, '0')) // 给空的那个填充 00 ,防止空缺
                .join(' '); // 每个子节之间空格隔开
            resolve(ret);
        };
        reader.readAsBinaryString(blob); // 调用之后触发onload事件
    });
    // 二进制=》ascii码=》转成16进制字符串
}

// 获取文件后缀
function getFileSuffix(filename) {
    return filename.substring(filename.lastIndexOf('.') + 1, filename.length);
}

判断是否是png类型:

async function isPng(file) {
    // 同理
    const ret = await blobToString(file.slice(0, 4));
    const ispng = ret === fileMap.PNG;
    return ispng;
}

当然也可以针对图片高宽进行限制:
png二进制中,第18-20位是图片的宽,22-24是高。

获取图片宽高:

function getRectByOffset(file, widthOffset, heightOffset, reverse) {
  let width = await blobToString(file.slice(...widthOffset));
  let height = await blobToString(file.slice(...heightOffset));

  const w = parseInt(width.replace(" ", ""), 16);
  const h = parseInt(height.replace(" ", ""), 16);
  return { w, h };
}

修改一下之前判断isPng的方法,加上高宽限制

const IMG_WIDTH_LIMIT = 1000;
const IMG_HEIGHT_LIMIT = 800
function isPng(file) {
  // 同理
  const ret = await this.blobToString(file.slice(0, 4));
  const ispng = ret === fileMap.PNG;
  if (ispng) {
    const { w, h } = await this.getRectByOffset(file, [18, 20], [22, 24]);
    console.log(`png 宽高 ${w},${h}`);
    if (w > IMG_WIDTH_LIMIT || h > IMG_HEIGHT_LIMIT) {
      this.$message.error(
        "png图片宽高不得超过 " + IMG_WIDTH_LIMIT + "和" + IMG_HEIGHT_LIMIT
      );
      return false;
    }
  }
  return ispng;
}

标签:function,文件,const,后缀,js,return,详解,file,文件类型
From: https://www.cnblogs.com/wp-leonard/p/17894444.html

相关文章

  • cesiumjs 点云
       用于提高细节细化级别的最大屏幕空间错误。该值有助于确定瓦片何时细化到其子代,因此在平衡性能和视觉质量方面发挥着重要作用。瓦片的屏幕空间误差大致相当于如果在瓦片的位置渲染半径等于瓦片几何误差的球体,则绘制的像素宽度。如果此值超过maximumScreenSpaceError......
  • quickjs集成http功能
    零、前言默认的quickjs,是js引擎,需要自己移植类似curl库,才能使quickjs有http请求功能。js引擎+一些本地功能调用=js运行时。一、libcurl库这个库的安装或编译,也是比较麻烦的事情,特别是需要使其支持https访问,配置和编译更是麻烦。因此,还是使用上次提到的vcpkg。通过vcpkg......
  • JS(JavaScript)-事件-Event事件
     1.介绍:事件就是可以被JS侦测到的行为。用户操作鼠标或键盘后,触发了JS事件,然后产生相应机制。 三要素:事件源:事件被触发的对象,就是谁触发了这个事件;事件类型:如何触发,什么事件;比如:鼠标点击,键盘按下事件处理程序:通过一个函......
  • moment.js
    //!moment.js//!version:2.29.4//!authors:TimWood,IskrenChernev,Moment.jscontributors//!license:MIT//!momentjs.com(function(global,factory){typeofexports==="object"&&typeofmodule!=="undefined"......
  • Unity3D 任务系统的架构与设计详解
    前言Unity3D是一款非常强大的游戏引擎,它提供了丰富的功能和工具,使得游戏开发变得更加简单和高效。在游戏开发中,任务系统是一个非常重要的组件,它可以使游戏更加有趣和挑战性。在本文中,我们将详细介绍Unity3D任务系统的架构与设计,包括技术详解和代码实现。对惹,这里有一个游戏开......
  • verifyCode.js
    functionGVerify(options){//创建一个图形验证码对象,接收options对象为参数this.options={//默认options参数值id:"",//容器IdcanvasId:"verifyCanvas",//canvas的IDwidth:"80",//默认canvas宽度height:"30",//默......
  • 232-父级div,包含子div,子div有点击事件,父div有点击事件,js如何实现,2个点击事件不干扰
    HTML结构<divid="parent"><divid="child"></div></div>JavaScript/jQuery代码:$(document).ready(function(){//父级div的点击事件处理程序$('#parent').on('click',function(){console.log(&#......
  • js获取当前页面域名判断跳转网址输出不同内容
    js代码可以实现一些html语言无法实现的功能,比如通过js代码获取当前访问的域名。通过js代码判断当前访问域名可以进行跳转等功能。js获取当前页面域名判断跳转网址代码:<scripttype="text/javascript"> host=window.location.host;if(host=="www.adminwl.com") { window.loca......
  • CommonJS 模块
    在Node.js中,每个文件都被视为一个单独的模块。CommonJS模块系统在 module 核心模块中实现。启用Node.js有两个模块系统:CommonJS模块和 ECMAScript模块。默认情况下,Node.js会将以下内容视为CommonJS模块:扩展名为 .cjs 的文件;当最近的父 package.json 文件......
  • 前端纯js字符串拼接导出excel
    1<html>2<head>3<pstyle="font-size:20px;color:red;">使用a标签方式将json导出csv文件</p>4<buttononclick='tableToExcel()'>导出</button>5</head>6<body>7<script>8......