HTML 提供了 <input type="file"> 元素用于实现文件上传功能,允许用户从本地选择文件并将其上传到服务器。
HTML 上传文件简介
文件上传功能我们经常用到,比如社交网站上传头像、网盘上传文档、发邮件添加附件等都会涉及这个功能。文件上传功能的实现需要用到后端技术,不过在学习 HTML 时,我们只需要关心把页面效果做出来就行了,功能实现不需要去深究。

在 HTML 中,上传文件控件也是使用 input 标签来实现的,其中 type 属性取值为 "file"。
语法:
<input type="file" name="字段名">说明:
<input type="file"> 元素有很多属性,常用的如下表所示。
| 属性 | 说明 |
|---|---|
| name | 设置上传控件的 “名称”,用于表单提交时标识上传的文件 |
| multiple | 是否允许用户选择多个文件,默认值为 false |
| accept | 限制可选文件的类型,比如 "image/*" 表示所有图片格式 |
| capture | 是否启用设备(如摄像头或麦克风)进行实时捕获,默认为 false |
| webkitdirectory | 是否允许用户选择文件夹,默认为 false(仅限 Chrome 和 Safari 支持) |
很多初学的小伙伴写了上传功能,后端却死活收不到文件。99% 的原因都是忘了设置 form 标签的 enctype 属性!
如果你的表单中包含了文件上传控件(type="file"),那么 form 标签必须写成下面这样:
<form action="/upload" method="post" enctype="multipart/form-data">
……
</form>也就是必须要加上 enctype="multipart/form-data"。这是因为在默认情况下,表单只是把数据 “编码” 成文本发送。但文件(图片、视频)是二进制数据。如果不加上 enctype="multipart/form-data",则浏览器只会把文件名发给服务器,而不是文件内容。
HTML 上传文件示例
接下来,我们通过几个简单的例子来讲解 HTML 上传文件控件是如何使用的。
示例 1:HTML 创建上传文件控件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
</form>
</body>
</html>页面效果如下图所示。

分析:
当我们点击【选择文件】按钮后会发现,怎么不能上传文件呢?其实这个需要学习后端技术(如 Node.js、Go、Java 等)之后才知道怎么实现,初学 HTML 时暂时不用管。
示例 2:限制上传文件的类型
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<h3>上传头像:</h3>
<input type="file" name="avatar" accept="image/*">
</form>
</body>
</html>
页面效果如下图所示。

分析:
在实际开发中,如果我们让用户上传头像,肯定不希望用户上传一个 Excel 表格。此时可以使用 accept 属性来限制上传文件的类型,比如:
- 只允许图片:accept="image/*"(支持 jpg, png, gif 等所有图片)。
- 只允许特定格式:accept=".jpg, .png"。
- 只允许 PDF:accept=".pdf"。
示例 3:允许一次上传多个文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form method="post" action="/">
<h3>上传相册(支持多选):</h3>
<input type="file" name="photos" accept="image/*" multiple>
</form>
</body>
</html>页面效果如下图所示。

分析:
默认情况下,一个输入框只能选择一个文件。如果想要一次性选择多张照片,我们可以使用 multiple 属性来实现。在选择文件的时候,我们可以按住 Ctrl 键或 Shift 键来实现多选。
常见问题
1. 文件上传按钮样式太丑,用户体验太差,如何解决这个问题?
浏览器默认的上传按钮非常丑,而且没法直接通过 CSS 修改。在实际开发中,我们可以把 <input type="file"> 隐藏起来(display: none),然后使用一个好看的 label 或者 button 去触发它。当然了,这个需要小伙伴学会了 CSS 才清楚如何实现。
2. 后端老是没办法收到上传的文件,是什么原因导致的?
如果发现文件没传上去,我们应该优先检查以下 3 点:
- form 标签有没有加 enctype="multipart/form-data"?
- form 标签的 method 是不是 post?(上传文件必须用 post)
- input 标签有没有写 name 属性?
3. 前端除了上传文件,还可以上传文件夹吗?
可以考虑使用 webkitdirectory 属性来实现,不过目前只有 Chrome 等部分浏览器支持这个属性,兼容性不是很好,不是很推荐使用。
