input[type="file"]的value属性显示fakepath是浏览器安全限制,真实文件名需通过input.files[0].name获取,且必须在onchange事件中判断files.length>0后读取。

input[type="file"] 的 value 属性为什么总是显示 fakepath?
浏览器出于安全限制,input[type="file"] 的 value 属性在 JS 中读取时,Windows 下会返回类似 C:\fakepath\filename.pdf 的字符串,Mac/Linux 下可能为空或只含文件名。这不是 bug,是规范行为——防止网页脚本窥探用户完整本地路径。
真正可用的文件信息藏在 input.files 这个 FileList 对象里,它才是获取真实文件名的唯一可靠入口。
用 onchange 事件 + files[0].name 显示上传文件名
监听 change 事件,在回调中访问 files[0](单文件上传)或遍历 files(多文件),取 name 属性即可拿到原始文件名。
- 必须用
onchange,而不是onclick或oninput—— 后者在未选中文件时也会触发,files可能为空 -
files是只读类数组,不能用forEach直接调用,需转成数组或用for循环 - 若用户取消选择或清空文件,
files.length为0,务必加判断避免Cannot read property 'name' of undefined
<input type="file" id="upload">
<span id="filename">未选择文件</span>
<script>
const input = document.getElementById('upload');
const span = document.getElementById('filename');
input.onchange = () => {
if (input.files.length > 0) {
span.textContent = input.files[0].name;
} else {
span.textContent = '未选择文件';
}
};
</script>
兼容多文件上传并显示全部文件名
当 input 带有 multiple 属性时,files 可能包含多个 File 对象。直接拼接 name 字符串容易被恶意文件名注入 HTML(如含 <script>),需做基础转义或用 textContent 渲染。
立即学习“前端免费学习笔记(深入)”;
- 用
Array.from(input.files).map(f => f.name)转换为真数组再处理 - 显示时建议用逗号分隔,或每行一个
<div>,避免单行过长 - 注意
files.length上限受浏览器限制(通常数万个),但实际业务中极少遇到
<input type="file" id="multi-upload" multiple>
<div id="file-list"></div>
<script>
const multiInput = document.getElementById('multi-upload');
const listEl = document.getElementById('file-list');
multiInput.onchange = () => {
const names = Array.from(multiInput.files).map(f => f.name);
listEl.innerHTML = names.length
? names.map(n => `<div>${n}</div>`).join('')
: '<div>未选择文件</div>';
};</script>
用 label 模拟点击 + 自定义样式隐藏原生 input
原生 input[type="file"] 样式难以统一,常见做法是将其透明度设为 0、绝对定位盖在自定义按钮上,再用 label[for] 关联实现“点按钮即触发选择”。此时文件名仍需靠 JS 从 files 获取并写入相邻元素。
- 必须设置
input的display: block和position: absolute,否则部分浏览器(如 Safari)无法响应点击 -
label需显式设置cursor: pointer,否则视觉反馈缺失 - 不要依赖
input.value更新显示 —— 它不可靠且跨浏览器不一致
关键点始终是:文件名来自 files[0].name,不是 value;显示逻辑必须绑定在 change 事件,且每次都要检查 files.length。



















