最直接可靠的判断方式是检查 input.files.length === 0;它适用于单选和多选,性能零开销,且比 value 或 jQuery.val() 更安全可靠。

用 input.files.length 判断前端是否选中文件
用户点“上传”但没选任何文件,input[type="file"] 的 files 是一个空的 FileList 对象,长度为 0。这是最直接、无副作用的判断方式:
- 不依赖表单提交时机,可在按钮点击、输入变化等任意时刻检查
- 无需读取内容或触发 DOM 重排,性能零开销
- 对单选和多选(
multiple)都适用:只要input.files.length === 0,就代表没选
示例:
const fileInput = document.getElementById('myFile');
if (fileInput.files.length === 0) {
alert('请先选择文件');
return;
}
// 后续可安全使用 fileInput.files[0]
别用 .value 或 $("...").val() 检查 file 输入
input[type="file"] 的 value 属性只返回文件名(且被浏览器限制为 fakepath),它在未选文件时是空字符串,但这个值不可靠:
- 即使用户选了文件,某些浏览器(如旧版 Safari)可能仍返回空字符串
- 恶意脚本可伪造
value,而files是只读、受保护的 DOM 属性,无法被篡改 - jQuery 的
.val()在 file input 上行为不一致,容易误判;必须用原生.files
错误写法:
立即学习“前端免费学习笔记(深入)”;
// ❌ 不要这样
if ($('#myFile').val() === '') { ... }
// ✅ 正确写法(jQuery 中也要取原生 files)
const fileInput = $('#myFile')[0];
if (fileInput.files.length === 0) { ... }
后端不能只信 header.Size 来判断空文件
前端没选文件,后端收到的是 http.ErrMissingFile;但若用户真传了个 0 字节文件,header.Size 可能被伪造或不准确——Go 官方明确建议:唯一可靠方式是尝试读取内容。
-
header.Size == 0不等于文件为空,只是请求头声称大小为 0 - 应调用
file.Read(buf)读 1 字节:若立即返回io.EOF,才是真空 - PHP 中同理:
$_FILES["f"]["size"] === 0不够,必须结合$_FILES["f"]["error"] === UPLOAD_ERR_OK且实际读取确认
创建 objectURL 前必须校验 files[0] 是否存在
URL.createObjectURL() 接收的是 Blob 或 File 实例,传 undefined 或 null 会直接抛 TypeError,中断 JS 执行。
- 永远先做存在性判断:
if (fileInput.files[0]) { URL.createObjectURL(fileInput.files[0]) } - 不要假设
files.length > 0就一定有files[0]—— 虽然通常成立,但防御性编程应显式检查 - 若需兼容多文件,遍历
files时也应逐个判空,而非只看 length
真正容易被忽略的点是:前端“未选文件”和后端“收到空文件”是两个独立问题,必须分层处理——前者靠 files.length 拦在 UI 层,后者靠服务端读字节兜底。漏掉任一环,都会让空文件悄悄穿过校验。



















