input的accept属性让文件上传安全高效

Written by

in

文章目录
  • 大部分前端开发,一提到“文件上传校验”,脑子里立刻蹦出三件事: 校验 MIME 类型 校验文件大小 再加一堆出错提示、兜底逻辑、边界处理 然后——自然地把这些事全扔给 JavaScript。 看起来很专业,对不对?直到有一天,我上传了一个文件,还没等它到后端,就被自己前端逻辑搞崩了。 于是我开始往代码里疯狂加条件、加双重判断、加“测试用特例”, 结果越补越乱,越写越心虚。 也就是在那段时间,我无意间翻出一个自己“从来没当回事”的 HTML 小特性。 这个小东西,直接改变了我处理文件上传的方式。 今天就把这个发现,从头讲给你听。
  • 大部分人处理上传,基本都是这样写: <input type=”file” id=”ImageUpload” /> 然后再配套一段 JavaScript 做校验: const fileInput = document.getElementById(‘ImageUpload’); fileInput.addEventListener(‘change’, (e) => { const inputFile = e.target.files[0]; if (!inputFile.type.startsWith(“image/”)) { alert(“You can upload only images.”); } }); 写完之后,内心是有点成就感的: “你看,我可以提示用户:你选错文件类型啦~” 但问题来了: 用户 已经点了按钮 已经打开系统文件选择器 已经在一大堆文件里翻来翻去 已经选好了一个文件 然后你跳出来说: “不行哦,这个传不上来。” 这就是典型的——事后教育式交互。 拖慢体验不说,错误率还高得离谱。 更扎心的是: 即便你写了这段 JavaScript 校验, 依然会遇到各种奇奇怪怪的测试样例: MIME 类型标错的文件 看起来是 image,实则不是图片 随便起了个后缀的二进制垃圾文件 把 PDF 假装成 PNG 的伪装文件 也就是说: 你费劲写了一堆前端验证, 但它既拦不住真高手,也常常在烦普通用户。 直到我遇见今天的主角。
  • 我说的就是这个东西: <input type=”file” accept=”image/*” /> 一个几乎所有人都见过、 却没几个人认真用过的属性:**accept**。 它小到只有几个字符, 但给上传体验带来的改变,是维度级别的: 在文件选择器里,自动隐藏所有不支持的文件 用户甚至 看不到错误类型可以选 自动根据 MIME 类型和后缀做过滤 兼容一大堆后台规定和浏览器格式细节 能轻松帮你砍掉 50%–60% 的上传校验代码 一句话: 用户选不到错的文件, 你就少写一半“事后骂人”的 JavaScript。
  • 当你这么写: <input type=”file” accept=”image/*” /> 接下来会发生什么? 用户点击上传按钮 打开系统的选文件窗口 窗口里只会展示“被认定为图片”的文件 诸如 PDF、DOC、乱七八糟的其他格式,统统隐藏 在这个阶段, 你的 JavaScript 甚至还没出场, 用户就已经被温柔地“拦在正确的范围里”。 如果你要上传的是 PDF 呢? <input type=”file” accept=”application/pdf” /> 再复杂一点,比如: 你想允许用户上传 多种类型:图片 + PDF: <input type=”file” accept=”.png, .jpg, .jpeg, .pdf” /> 只想要视频? <input type=”file” accept=”video/*” /> 只要音频? <input type=”file” accept=”audio/*” /> 只要 Office 文件(Word / Excel / PPT)? <input type=”file” accept=”.docx, .xlsx, .pptx” /> 这些全都只是 HTML 在帮你干活。 你甚至不需要写一行 JS, 就能把 90% 的“明显错误文件”挡在门外。
  • 当然,现实项目里,你往往不只关心“格式对不对”。 比如: “必须是 PDF,且不能超过 2MB。” 这时候你就不用搞“二选一”—— 不是“要么用 accept”, 也不是“只用 JS 校验”。 最聪明的做法,是:两者叠加使用。 先用 HTML 把格式错得离谱的全部挡掉, 再用 JavaScript 做更细节的逻辑,比如文件大小。 举个简化版例子: <input type=”file” id=”resumeFile” accept=”.pdf” /> document.getElementById(“resumeFile”).addEventListener(“change”, (e) => { const file = e.target.files[0]; if (file.size > 2 * 1024 * 1024) { alert(“You can upload the file of maximum 2MB only.”); e.target.value = “”; // 清空选择 } }); 这样一来: HTML 帮你挡掉 非 PDF 的所有文件 JS 再帮你筛掉 超过 2MB 的那部分 到了后端,你再进行最终验证: 再判断 MIME 再判断大小 再检验文件内容是否真的是你要的类型 这才是一个真正安全又顺滑的上传流程: 第一道关:accept(友好 + 直观) 第二道关:前端 JS(体验 + 提前反馈) 第三道关:后端校验(绝对安全兜底)
  • 很多时候,你上传的不是“所有图片”, 而是特定格式,比如只要 PNG 和 MP4。 以前很多人第一反应是: “写个复杂点的正则吧。” 但其实,只要这样写就够了: <input type=”file” accept=”image/png, video/mp4″ /> 再比如,你的后台只接受 CSV: <input type=”file” accept=”.csv, text/csv” /> 这背后复杂的 MIME 映射、兼容性细节、各种边界情况, 浏览器已经帮你扛了大半。 你只要静静地写对 accept 里的字符串就行。 不用上第三方组件, 不用写一堆莫名其妙的兼容代码, HTML 本身就足够强。
  • 很多人听到这里,第一个问题是: “这么好用,会不会只在个别浏览器有效?” 简单给你一句话版结论: accept 属性,在主流平台上几乎是全量支持: Chrome ✔ Firefox ✔ Safari ✔ Edge ✔ iOS Safari ✔ Android Chrome ✔ 也就是说: 你可以非常安心地在正常项目里,上这个属性。
  • 我并不是说: “用 HTML 就够了,JavaScript 都删掉吧。” JavaScript 在上传逻辑里,依然非常重要: 尺寸校验 多文件规则 上传进度条 异步请求、重试机制 各种复杂业务约束 这些都是 HTML 做不到的地方。 我想说的是: 有些事情,HTML 已经帮你想好了, 你再用 JS 去重复造轮子, 不仅费力,还容易写出 bug。 有时候,一行写错的 JS, 能让你整个上传逻辑直接翻车; 而一个正确的 HTML 属性, 则可以在问题发生之前,就悄悄帮你挡掉一半错误输入。
  • 文件类型 扩展名 MIME类型 JPEG图像 .jpg, .jpeg image/jpeg PNG图像 .png image/png GIF图像 .gif image/gif WebP图像 .webp image/webp SVG图像 .svg image/svg+xml PDF文档 .pdf application/pdf Word文档 .doc application/msword Word文档 .docx application/vnd.openxmlformats-officedocument.wordprocessingml.document Excel文件 .xls application/vnd.ms-excel Excel文件 .xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet PPT文件 .ppt application/vnd.ms-powerpoint PPT文件 .pptx application/vnd.openxmlformats-officedocument.presentationml.presentation 文本文件 .txt text/plain HTML文件 .html, .htm text/html CSS文件 .css text/css JavaScript .js application/javascript JSON文件 .json application/json XML文件 .xml application/xml ZIP压缩 .zip application/zip RAR压缩 .rar application/x-rar-compressed 7Z压缩 .7z application/x-7z-compressed MP3音频 .mp3 audio/mpeg WAV音频 .wav audio/wav OGG音频 .ogg audio/ogg MP4视频 .mp4 video/mp4 AVI视频 .avi video/x-msvideo MOV视频 .mov video/quicktime
  • 如果你今天只能带走一件事,那就是: 下次写 <input type="file"> 的时候, 先想想:“我到底允许什么类型?” 然后,老老实实写上 accept。 从此以后,你会发现: 用户不再频繁选错文件 你的错误弹窗少了一半 你可以删掉一堆啰嗦的前端类型校验 上传流程变得“自然顺滑”,而不是“处处设陷阱” HTML 没有突然变聪明。 只是我们过去很多年, 把它当成了“只能画表单的塑料壳”, 忘了它其实有很多细腻的小能力,可以让体验变得更优雅。 写得越久,我越服的一句话是: 代码不一定要写得花哨, 但一定要优先把 已有的好工具,用明白。 accept 就是这样的工具之一。 用过一次,你就再也不会回去写那种: “上来不设限制、事后狂 alert 用户”的上传逻辑了。 accept 属性是提高用户体验的重要工具,但需要注意: 不是安全措施:可以被绕过,必须进行服务器验证 提供良好UX:帮助用户快速找到正确文件 结合其他属性:与 multiple、capture 等属性配合使用 现代浏览器支持:大部分浏览器都支持,但移动端行为可能不同 到此这篇关于input的accept属性让文件上传安全高效的文章就介绍到这了,更多相关input文件上传的accept属性内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: javascript input图片上传及预览,FileReader预览图片 jQuery实现input[type=file]多图预览上传删除等功能 js自定义input文件上传样式 如何用input标签和jquery实现多图片的上传和回显功能 最好用的Bootstrap fileinput.js文件上传组件 javascript实现input file上传图片预览效果 上传图片预览JS脚本 Input file图片预览的实现示例 js 实现 input type="file" 文件上传示例代码
  • 目录
    • 前言
    • 那个悄悄毁掉你上传体验的“常见写法”
    • 改变一切的 HTML 小特性:accept
    • 真正的魔法:让用户一开始就没机会选错
    • 那如果我需要更精细的控制呢?
    • 多种文件类型的“精确过滤”,完全不需要第三方库
    • 浏览器支持情况:能跑的地方,几乎都能用
    • 再强调一次:不是说不要 JS,而是别让 JS 做本不该它做的事
    • 常见文件类型对应的MIME类型:
    • 最后的小结:学会用好这一行,你会讨厌你以前的写法

    大部分前端开发,一提到“文件上传校验”,脑子里立刻蹦出三件事:

    • 校验 MIME 类型

    • 校验文件大小

    • 再加一堆出错提示、兜底逻辑、边界处理

    然后——自然地把这些事全扔给 JavaScript。

    看起来很专业,对不对?直到有一天,我上传了一个文件,还没等它到后端,就被自己前端逻辑搞崩了。

    于是我开始往代码里疯狂加条件、加双重判断、加“测试用特例”, 结果越补越乱,越写越心虚。

    也就是在那段时间,我无意间翻出一个自己“从来没当回事”的 HTML 小特性。

    这个小东西,直接改变了我处理文件上传的方式。

    今天就把这个发现,从头讲给你听。

    大部分人处理上传,基本都是这样写:

    <input type="file" id="ImageUpload" />

    然后再配套一段 JavaScript 做校验:

    const fileInput = document.getElementById('ImageUpload');
    
    fileInput.addEventListener('change', (e) => {
      const inputFile = e.target.files[0];
    
      if (!inputFile.type.startsWith("image/")) {
        alert("You can upload only images.");
      }
    });

    写完之后,内心是有点成就感的:

    “你看,我可以提示用户:你选错文件类型啦~”

    但问题来了:

    • 用户 已经点了按钮

    • 已经打开系统文件选择器

    • 已经在一大堆文件里翻来翻去

    • 已经选好了一个文件

    然后你跳出来说:

    “不行哦,这个传不上来。”

    这就是典型的——事后教育式交互。 拖慢体验不说,错误率还高得离谱。

    更扎心的是: 即便你写了这段 JavaScript 校验, 依然会遇到各种奇奇怪怪的测试样例:

    • MIME 类型标错的文件

    • 看起来是 image,实则不是图片

    • 随便起了个后缀的二进制垃圾文件

    • 把 PDF 假装成 PNG 的伪装文件

    也就是说:

    你费劲写了一堆前端验证, 但它既拦不住真高手,也常常在烦普通用户。

    直到我遇见今天的主角。

    我说的就是这个东西:

    <input type="file" accept="image/*" />

    一个几乎所有人都见过、 却没几个人认真用过的属性:**accept**。

    它小到只有几个字符, 但给上传体验带来的改变,是维度级别的:

    • 在文件选择器里,自动隐藏所有不支持的文件

    • 用户甚至 看不到错误类型可以选

    • 自动根据 MIME 类型和后缀做过滤

    • 兼容一大堆后台规定和浏览器格式细节

    • 能轻松帮你砍掉 50%–60% 的上传校验代码

    一句话:

    用户选不到错的文件, 你就少写一半“事后骂人”的 JavaScript。

    当你这么写:

    <input type="file" accept="image/*" />

    接下来会发生什么?

    • 用户点击上传按钮

    • 打开系统的选文件窗口

    • 窗口里只会展示“被认定为图片”的文件

    • 诸如 PDF、DOC、乱七八糟的其他格式,统统隐藏

    在这个阶段, 你的 JavaScript 甚至还没出场, 用户就已经被温柔地“拦在正确的范围里”。

    如果你要上传的是 PDF 呢?

    <input type="file" accept="application/pdf" />

    再复杂一点,比如: 你想允许用户上传 多种类型:图片 + PDF:

    <input type="file" accept=".png, .jpg, .jpeg, .pdf" />

    只想要视频?

    <input type="file" accept="video/*" />

    只要音频?

    <input type="file" accept="audio/*" />

    只要 Office 文件(Word / Excel / PPT)?

    <input type="file" accept=".docx, .xlsx, .pptx" />

    这些全都只是 HTML 在帮你干活。 你甚至不需要写一行 JS, 就能把 90% 的“明显错误文件”挡在门外。

    当然,现实项目里,你往往不只关心“格式对不对”。 比如:

    “必须是 PDF,且不能超过 2MB。”

    这时候你就不用搞“二选一”——

    不是“要么用 accept”, 也不是“只用 JS 校验”。

    最聪明的做法,是:两者叠加使用

    先用 HTML 把格式错得离谱的全部挡掉, 再用 JavaScript 做更细节的逻辑,比如文件大小。

    举个简化版例子:

    <input type="file" id="resumeFile" accept=".pdf" />
    document.getElementById("resumeFile").addEventListener("change", (e) => {
      const file = e.target.files[0];
    
      if (file.size > 2 * 1024 * 1024) {
        alert("You can upload the file of maximum 2MB only.");
        e.target.value = ""; // 清空选择
      }
    });

    这样一来:

    • HTML 帮你挡掉 非 PDF 的所有文件

    • JS 再帮你筛掉 超过 2MB 的那部分

    到了后端,你再进行最终验证:

    • 再判断 MIME

    • 再判断大小

    • 再检验文件内容是否真的是你要的类型

    这才是一个真正安全又顺滑的上传流程:

    第一道关:accept(友好 + 直观)

    第二道关:前端 JS(体验 + 提前反馈)

    第三道关:后端校验(绝对安全兜底)

    很多时候,你上传的不是“所有图片”, 而是特定格式,比如只要 PNG 和 MP4。

    以前很多人第一反应是: “写个复杂点的正则吧。”

    但其实,只要这样写就够了:

    <input type="file" accept="image/png, video/mp4" />

    再比如,你的后台只接受 CSV:

    <input type="file" accept=".csv, text/csv" />

    这背后复杂的 MIME 映射、兼容性细节、各种边界情况, 浏览器已经帮你扛了大半。

    你只要静静地写对 accept 里的字符串就行。

    不用上第三方组件, 不用写一堆莫名其妙的兼容代码, HTML 本身就足够强。

    很多人听到这里,第一个问题是:

    “这么好用,会不会只在个别浏览器有效?”

    简单给你一句话版结论:

    accept 属性,在主流平台上几乎是全量支持

    • Chrome ✔

    • Firefox ✔

    • Safari ✔

    • Edge ✔

    • iOS Safari ✔

    • Android Chrome ✔

    也就是说: 你可以非常安心地在正常项目里,上这个属性。

    我并不是说:

    “用 HTML 就够了,JavaScript 都删掉吧。”

    JavaScript 在上传逻辑里,依然非常重要:

    • 尺寸校验

    • 多文件规则

    • 上传进度条

    • 异步请求、重试机制

    • 各种复杂业务约束

    这些都是 HTML 做不到的地方。

    我想说的是:

    有些事情,HTML 已经帮你想好了, 你再用 JS 去重复造轮子, 不仅费力,还容易写出 bug。

    有时候,一行写错的 JS, 能让你整个上传逻辑直接翻车; 而一个正确的 HTML 属性, 则可以在问题发生之前,就悄悄帮你挡掉一半错误输入。

    文件类型 扩展名 MIME类型
    JPEG图像 .jpg, .jpeg image/jpeg
    PNG图像 .png image/png
    GIF图像 .gif image/gif
    WebP图像 .webp image/webp
    SVG图像 .svg image/svg+xml
    PDF文档 .pdf application/pdf
    Word文档 .doc application/msword
    Word文档 .docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
    Excel文件 .xls application/vnd.ms-excel
    Excel文件 .xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    PPT文件 .ppt application/vnd.ms-powerpoint
    PPT文件 .pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
    文本文件 .txt text/plain
    HTML文件 .html, .htm text/html
    CSS文件 .css text/css
    JavaScript .js application/javascript
    JSON文件 .json application/json
    XML文件 .xml application/xml
    ZIP压缩 .zip application/zip
    RAR压缩 .rar application/x-rar-compressed
    7Z压缩 .7z application/x-7z-compressed
    MP3音频 .mp3 audio/mpeg
    WAV音频 .wav audio/wav
    OGG音频 .ogg audio/ogg
    MP4视频 .mp4 video/mp4
    AVI视频 .avi video/x-msvideo
    MOV视频 .mov video/quicktime

    如果你今天只能带走一件事,那就是:

    下次写 <input type="file"> 的时候, 先想想:“我到底允许什么类型?”

    然后,老老实实写上 accept

    从此以后,你会发现:

    • 用户不再频繁选错文件

    • 你的错误弹窗少了一半

    • 你可以删掉一堆啰嗦的前端类型校验

    • 上传流程变得“自然顺滑”,而不是“处处设陷阱”

    HTML 没有突然变聪明。 只是我们过去很多年, 把它当成了“只能画表单的塑料壳”, 忘了它其实有很多细腻的小能力,可以让体验变得更优雅。

    写得越久,我越服的一句话是:

    代码不一定要写得花哨, 但一定要优先把 已有的好工具,用明白。

    accept 就是这样的工具之一。

    用过一次,你就再也不会回去写那种: “上来不设限制、事后狂 alert 用户”的上传逻辑了。

    accept 属性是提高用户体验的重要工具,但需要注意:

    • 不是安全措施:可以被绕过,必须进行服务器验证

    • 提供良好UX:帮助用户快速找到正确文件

    • 结合其他属性:与 multiplecapture 等属性配合使用

    • 现代浏览器支持:大部分浏览器都支持,但移动端行为可能不同

    到此这篇关于input的accept属性让文件上传安全高效的文章就介绍到这了,更多相关input文件上传的accept属性内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

    您可能感兴趣的文章:

    • javascript input图片上传及预览,FileReader预览图片
    • jQuery实现input[type=file]多图预览上传删除等功能
    • js自定义input文件上传样式
    • 如何用input标签和jquery实现多图片的上传和回显功能
    • 最好用的Bootstrap fileinput.js文件上传组件
    • javascript实现input file上传图片预览效果
    • 上传图片预览JS脚本 Input file图片预览的实现示例
    • js 实现 input type="file" 文件上传示例代码

    站内搜索