input.files[0].name 是唯一可靠获取文件名的方式,因 input.value 受浏览器安全限制返回 fakepath 或空字符串;必须在 change 事件中读取 files,并用 array.from 转换后处理,渲染时优先用 textcontent 防 xss。

input.files[0].name 是唯一可靠的方式,input.value 返回 C:\fakepath\... 或空字符串,不是 bug,是浏览器安全限制。
为什么不能用 input.value 读文件名
Windows 下 input.value 会返回带 fakepath 的路径,Mac/Linux 可能为空;这是规范行为,防止网页获取用户本地完整路径。真实文件信息只存在于 input.files 这个只读 FileList 对象中。
- 必须在
change事件中读取 ——click或input事件可能触发时files还没更新 -
files是类数组,不能直接调用forEach,得用Array.from(files)或for循环 - 用户取消选择后
files.length === 0,不加判断会报Cannot read property 'name' of undefined
单文件上传:显示 + 截断 + 悬停全名
直接渲染长文件名容易撑破容器或换行,推荐 JS 动态截断并设 title 属性:
- 用
files[0].name获取原始名,再按需截取(如前 16 字符 +…) - 把完整文件名写进
title属性,悬停即可见 - 设置
displayEl.textContent和displayEl.title保持同步,清空时一并置空 - 避免用
innerHTML渲染文件名,防恶意字符串注入(如含<script></script>)
多文件上传:安全拼接与 DOM 渲染
带 multiple 属性时,files 可含多个 File 对象:
- 用
Array.from(files).map(f => f.name)转为真数组再处理 - 拼接建议用逗号分隔,或每个文件名单独一个
<div>,避免单行过长 <li>不做 HTML 转义就直接拼进 <code>innerHTML,有 XSS 风险;优先用textContent - 浏览器对
files.length有上限(通常数万),但业务中几乎不会触达
最易被忽略的是:files 对象只在 change 触发后才有效,且不可写;任何试图修改它的操作(比如 files[0] = new File(...))都会静默失败。别想绕过这个限制,它就是设计如此。











