在Web开发中,文件上传是常见功能,很多时候我们需要在上传前让用户预览选中的文件内容,比如图片、文本等。用JS实现文件上传预览不需要依赖第三方库,核心是利用浏览器提供的文件相关API。

核心API介绍
实现文件上传预览主要依赖两个核心对象:HTMLInputElement的files属性和FileReader对象。
files属性:当用户通过<input type="file">选择文件后,该属性会返回一个FileList对象,里面包含了用户选中的所有文件信息,每个文件都是File实例,包含文件名、大小、类型等属性。FileReader:用于读取文件内容,提供了多种读取方法,比如读取为Data URL、读取为文本等,读取完成后会触发对应的回调,我们可以在回调中获取到文件的内容用于预览。
基础实现步骤
1. 创建文件上传控件
首先在页面中添加一个文件上传的input元素,以及用于展示预览内容的容器。
<input type="file" id="fileInput" accept="image/*,text/plain" multiple> <div id="previewContainer"></div>
这里accept属性限制了可选的文件类型为图片和纯文本,multiple属性允许选择多个文件,你可以根据实际需求调整这些属性。
2. 监听文件选择事件
给input元素添加change事件监听,当用户选择文件后触发处理逻辑。
const fileInput = document.getElementById('fileInput');
const previewContainer = document.getElementById('previewContainer');
fileInput.addEventListener('change', function() {
// 清空之前的预览内容
previewContainer.innerHTML = '';
const files = this.files;
if (!files.length) return;
// 遍历所有选中的文件进行处理
Array.from(files).forEach(file => {
handleFilePreview(file);
});
});
3. 处理不同类型文件的预览
根据文件的类型,选择不同的预览方式,常见的图片文件可以转为Data URL展示,文本文件可以读取为文本内容展示。
function handleFilePreview(file) {
const reader = new FileReader();
// 判断文件类型
if (file.type.startsWith('image/')) {
// 图片文件读取为Data URL
reader.readAsDataURL(file);
reader.onload = function(e) {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '300px';
img.style.margin = '10px';
previewContainer.appendChild(img);
};
} else if (file.type === 'text/plain') {
// 文本文件读取为文本
reader.readAsText(file);
reader.onload = function(e) {
const pre = document.createElement('pre');
pre.textContent = e.target.result;
pre.style.maxHeight = '200px';
pre.style.overflow = 'auto';
pre.style.border = '1px solid #ccc';
pre.style.padding = '10px';
pre.style.margin = '10px';
previewContainer.appendChild(pre);
};
} else {
// 其他类型文件提示不支持预览
const p = document.createElement('p');
p.textContent = `不支持预览文件类型:${file.name}`;
previewContainer.appendChild(p);
}
// 读取错误处理
reader.onerror = function() {
const p = document.createElement('p');
p.textContent = `读取文件${file.name}失败`;
previewContainer.appendChild(p);
};
}
注意事项
- FileReader的读取是异步操作,所有预览逻辑需要放在对应的onload回调中执行。
- 如果用户选择大文件,读取过程可能会占用一定内存,建议对文件大小做限制,避免页面卡顿。
- 部分浏览器对FileReader的兼容性较好,如果需要兼容非常老的浏览器,需要提前做兼容性判断。
- 预览生成的Data URL如果不需要了,可以及时清空对应的DOM元素,释放内存。
完整示例代码
以下是整合了所有逻辑的完整可运行代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS文件上传预览示例</title>
</head>
<body>
<h3>文件上传预览</h3>
<input type="file" id="fileInput" accept="image/*,text/plain" multiple>
<div id="previewContainer"></div>
<script>
const fileInput = document.getElementById('fileInput');
const previewContainer = document.getElementById('previewContainer');
fileInput.addEventListener('change', function() {
previewContainer.innerHTML = '';
const files = this.files;
if (!files.length) return;
Array.from(files).forEach(file => {
handleFilePreview(file);
});
});
function handleFilePreview(file) {
const reader = new FileReader();
if (file.type.startsWith('image/')) {
reader.readAsDataURL(file);
reader.onload = function(e) {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '300px';
img.style.margin = '10px';
previewContainer.appendChild(img);
};
} else if (file.type === 'text/plain') {
reader.readAsText(file);
reader.onload = function(e) {
const pre = document.createElement('pre');
pre.textContent = e.target.result;
pre.style.maxHeight = '200px';
pre.style.overflow = 'auto';
pre.style.border = '1px solid #ccc';
pre.style.padding = '10px';
pre.style.margin = '10px';
previewContainer.appendChild(pre);
};
} else {
const p = document.createElement('p');
p.textContent = `不支持预览文件类型:${file.name}`;
previewContainer.appendChild(p);
}
reader.onerror = function() {
const p = document.createElement('p');
p.textContent = `读取文件${file.name}失败`;
previewContainer.appendChild(p);
};
}
</script>
</body>
</html>
JS文件上传文件预览FileReader修改时间:2026-07-06 15:33:29