2026-05-30 11:34:43
JavaScript 实现文件上传预览的核心在于读取文件内容并展示在页面上,常用方法包括 FileReader、URL.createObjectURL()、第三方库等。以下是五种技术方案及代码示例:

原理:通过 FileReader 异步读取文件内容,转换为 Data URL 后赋值给 <img> 标签的 src 属性。适用场景:图片文件预览,兼容性好但大文件性能较差。代码示例:
const fileInput = document.getElementById('fileInput');const previewImage = document.getElementById('previewImage');fileInput.addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { previewImage.src = e.target.result; }; reader.readAsDataURL(file); }});方案二:基于 URL.createObjectURL() 的图片预览原理:创建指向内存中对象的 URL,直接赋值给 <img> 标签,处理大文件效率更高。注意事项:需手动释放 URL 对象,避免内存泄漏。代码示例:
const fileInput = document.getElementById('fileInput');const previewImage = document.getElementById('previewImage');fileInput.addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const objectURL = URL.createObjectURL(file); previewImage.src = objectURL; previewImage.onload = function() { URL.revokeObjectURL(objectURL); // 释放 URL }; }});方案三:预览非图片文件(如 PDF)原理:使用 <object> 或 <iframe> 标签加载文件,依赖浏览器对文件类型的支持。适用场景:PDF、Word 等非图片文件预览。代码示例:
<input type="file" id="fileInput" accept=".pdf"><object id="previewObject" data="" type="application/pdf" width="600" height="400"></object>const fileInput = document.getElementById('fileInput');const previewObject = document.getElementById('previewObject');fileInput.addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const objectURL = URL.createObjectURL(file); previewObject.data = objectURL; previewObject.onload = function() { URL.revokeObjectURL(objectURL); }; }});方案四:使用第三方库(如 FilePond)原理:通过集成第三方库(如 FilePond、Dropzone.js)简化开发,提供拖拽上传、进度条等功能。优点:减少开发工作量,功能丰富。代码示例:
<input type="file" class="filepond" name="filepond" multiple>// 引入 FilePond 样式和脚本FilePond.registerPlugin( FilePondPluginImagePreview, FilePondPluginFileValidateType);const pond = FilePond.create( document.querySelector('.filepond'), { acceptedFileTypes: ['image/*'], imagePreviewHeight: 170, });FilePond.setOptions({ server: '/api' // 配置上传接口});方案五:结合 Canvas 实现高级图片处理原理:通过 Canvas API 对图片进行缩放、裁剪、添加水印等操作。适用场景:需要自定义图片处理的场景。代码示例:
<input type="file" id="fileInput"><canvas id="previewCanvas" width="300" height="200"></canvas>const fileInput = document.getElementById('fileInput');const previewCanvas = document.getElementById('previewCanvas');const ctx = previewCanvas.getContext('2d');fileInput.addEventListener('change', function(event) { const file = event.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { const img = new Image(); img.onload = function() { ctx.drawImage(img, 0, 0, previewCanvas.width, previewCanvas.height); }; img.src = e.target.result; }; reader.readAsDataURL(file); }});性能优化方案客户端:通过 <input accept="image/*"> 和 file.type 检查。
服务端:验证 MIME 类型和扩展名,防止篡改。
使用 polyfill 补充老旧浏览器不支持的 API。
通过特性检测(如 if ('FileReader' in window))判断 API 支持情况。
扫描文件内容,隔离存储上传文件。
过滤文件名中的特殊字符,防止注入攻击。

根据项目需求选择合适的方案:简单图片预览可用 FileReader 或 URL.createObjectURL();需要高级功能可集成第三方库;对图片处理有特殊要求时结合 Canvas 实现。