JS 判断文件是否是图片

本贴最后更新于 3625 天前,其中的信息可能已经沧海桑田

JS 判断文件是否为图片,原理就是检测文件的 Magic Number

对 JPEG、GIF、PNG 的 magic number 的检测如下:

var pngMagic = [ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a ]; var jpeg_jfif = [ 0x4a, 0x46, 0x49, 0x46 ]; var jpeg_exif = [ 0x45, 0x78, 0x69, 0x66 ]; var jpegMagic = [ 0xFF, 0xD8, 0xFF, 0xE0 ]; var gifMagic0 = [ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 ]; var getGifMagic1 = [ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 ]; function arraycopy(src, index, dist, distIndex, size) { for (i = 0; i < size; i++) { dist[distIndex + i] = src[index + i] } } function arrayEquals(arr1, arr2) { console.log(arr1) console.log(arr2) if (arr1 == 'undefined' || arr2 == 'undefined') { return false } if (arr1 instanceof Array && arr2 instanceof Array) { if (arr1.length != arr2.length) { return false } for (i = 0; i < arr1.length; i++) { if (arr1[i] != arr2[i]) { return false } } return true } return false; } function isImage(buf) { if (buf == null || buf == 'undefined' || buf.length < 8) { return null; } var bytes = []; arraycopy(buf, 0, bytes, 0, 6); if (isGif(bytes)) { return "image/gif"; } bytes = []; arraycopy(buf, 6, bytes, 0, 4); if (isJpeg(bytes)) { return "image/jpeg"; } bytes = []; arraycopy(buf, 0, bytes, 0, 8); if (isPng(bytes)) { return "image/png"; } return null; } /** * @param data first 6 bytes of file * @return gif image file true,other false */ function isGif(data) { console.log('GIF') return arrayEquals(data, gifMagic0) || arrayEquals(data, getGifMagic1); } /** * @param data first 4 bytes of file * @return jpeg image file true,other false */ function isJpeg(data) { console.log('JPEG') return arrayEquals(data, jpegMagic) || arrayEquals(data, jpeg_jfif) || arrayEquals(data, jpeg_exif); } /** * @param data first 8 bytes of file * @return png image file true,other false */ function isPng(data) { console.log('PNG') return arrayEquals(data, pngMagic); }

在 HTML 中使用如下:

function handleFileSelect(evt) { var files = evt.target.files; if (files[0]) { var reader = new FileReader(); reader.onload = fileLoaded; //读取文件为ArrayBuffer reader.readAsArrayBuffer(files[0]); } } function fileLoaded(evt) { //取前11Bytes转换成Uint8Array var fileBuf = new Uint8Array(evt.target.result.slice(0, 11)); //调用之前的方法判断是不是图片 //如果不是返回null,否则返回mimeType var mime = isImage(fileBuf); alert(mime) } //对 input 注册change 事件监听 var fileInput = document.getElementById('file'); fileInput.addEventListener('change', handleFileSelect, false);
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    730 引用 • 1281 回帖 • 1 关注
  • 图片
    25 引用 • 124 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 88250

    👍 社区会参考这个加入上传时的判断的

  • 88250

    已经用上了,请大家帮忙测试~

  • muyuballs
    作者

    @88250 pdf 伪装成 .png 已经不行了

  • 88250

    😄 感觉安全一些了

  • Chan
    var fileInput = document.getElementById('file'); fileInput[0].files.type.indexOf('png/jpg/xxxx') != 0;

    这样也行吧

  • muyuballs
    作者

    @Chan 这样就要看浏览器是不是通过后缀名来判断类型了,万一是病毒伪装成.png 呢

请输入回帖内容 ...

推荐标签 标签

  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    227 引用 • 476 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 751 回帖 • 1 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 537 关注
  • Excel
    31 引用 • 28 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 2 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 5 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    172 引用 • 534 回帖 • 1 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 8 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    113 引用 • 315 回帖
  • 反馈

    Communication channel for makers and users.

    122 引用 • 912 回帖 • 277 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 31 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    89 引用 • 113 回帖
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    7 引用 • 27 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 52 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    79 引用 • 396 回帖
  • 工具

    子曰:“工欲善其事,必先利其器。”

    298 引用 • 763 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 8 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖 • 1 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 256 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 59 回帖 • 4 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 662 关注