JavaScript File API实现本地图片上传与预览

作者:闭包旅人

时间:2026-10-29

浏览:567

本文介绍如何使用HTML5 File API和FileReader对象在浏览器端实现本地文件的读取与预览。通过监听input元素的change事件获取文件信息,利用FileReader的readAsDataURL等方法异步读取文件内容并转换为Data URL,从而在上传服务器前完成图片预览,提升用户体验。

文章目录

传统文件上传的局限性

在基于浏览器的应用中,访问本地文件一直是一个挑战。传统方式通常仅能使用<input type="file">标签来上传文件。其工作流程是:用户选择文件时,value属性保存文件名;表单提交时,浏览器会将文件内容而非仅文件名发送给服务器。随后,开发者需获取服务器返回的文件地址,才能进行展示或预览。

然而,若需求是上传一张图片后立即预览,且用户希望更换图片,传统流程要求先将新图片上传至服务器,再获取地址进行预览。在网络环境不佳时,这种反复上传与等待的过程会显著降低用户体验。

因此,在某些场景下(如需要剪切图片的头像更换功能,类似新浪微博),先预览再上传至服务器显得尤为重要。过去,实现多浏览器兼容通常依赖Flash或复杂插件,导致代码维护困难。如今,File API的引入解决了这一难题。

File API与文件信息获取

通过监听input元素的change事件,可以获知用户选择的文件。此时,input元素新增了一个files集合,其中包含File对象。每个File对象代表一个文件,并具备以下只读属性:name(文件名)、size(文件大小)、type(MIME类型)以及lastModifiedDate(最后修改时间)。

以<input type="file" name="file">为例,监控onchange事件并打印其file对象,可以直观看到文件的具体信息。

  传统文件上传的局限性

通过上述方式,我们可以获取用户选取的文件格式、文件名及大小等信息。这使得在前端对文件进行验证,判断其是否符合预设要求变得简单直接。

FileReader异步读取机制

此外,File API还提供了FileReader类型,用于读取文件中的数据内容。

FileReader实现了一种异步文件读取机制,类似于XMLHttpRequest,但它是从本地文件系统而非远程服务器读取数据。它提供了多种读取方法:

  • readAsText(file, encoding):以纯文本形式读取文件,结果保存在result属性中。第二个参数用于指定编码类型,为可选参数。
  • readAsDataURL(file):读取文件,并将结果以数据URL(Data URL)的形式保存在result属性中。
  • readAsBinaryString(file):读取文件,并将文件内容作为二进制字符串保存在result属性中。
  • readAsArrayBuffer(file):读取文件,并将包含文件内容的ArrayBuffer对象保存在result属性中。

通过上述方法分别读取同一张本地图片,并将保存在result属性中的信息打印出来进行对比,结果如下:

readAsText(file, encoding)的读取结果示例:

传统文件上传的局限性

readAsDataURL(file)的读取结果示例:

传统文件上传的局限性

通过对比发现,这些读取文件的方法为灵活处理文件数据提供了极大便利。例如,将图像文件读取并保存为Data URL,即可实现上传前的本地预览功能。

由于读取过程是异步的,FileReader对象提供了几个事件来处理不同状态:progress(读取新数据时触发)、error(发生错误时触发)以及load(文件读取完成时触发)。

若因各种原因无法读取文件,将触发error事件。此时,FileReader的error属性中将包含一个对象,其code属性记录了具体的错误码。

实现图片上传预览示例

以下是一个使用FileReader实现上传预览的完整示例:

HTML结构部分:


<label class="item_label">上传照片:
 <span style="width: 100px; height: 100px;border:1px solid #ccc; display:inline-block"><img src="#" id="uploadPreview" style="width: 100%; height: 100%;"></span>
 <input type="file" name="file" id="postFile" style="width:74px;">
 <span id="error_text" style="display: none;">提示</span>
</label>
  

JavaScript逻辑部分:


document.getElementById('postFile').onchange = function() {
 var val = this.value;
 var upLoadType = '.jpg,.gif,.bmp,.png';//['.jpg','.gif','.bmp','.png']; //可上传的格式
 var fileExt = val.substr(val.lastIndexOf(".")).toLowerCase(); //从字符串中抽出最后一次出现.之后的字符,并且转换成小写
 var result = upLoadType.indexOf(fileExt); //查找后缀名是否符合条件,如果符合返回>=0,如果不符合则返回负数;
 _alertMsg = $('#error_text');
 var oFReader = new FileReader();
 if (this.files.length === 0) { return; }
 var oFile = this.files[0]; //如果只有一个文件则只需要访问这个FileList对象中的第一个元素.
  
 if (oFile.size / 1024 < 100) {
  _alertMsg.html("<font style='color:blue'>√</font>").show()
 };
 if (result < 0) {
  _alertMsg.html("请输入正确格式:" + upLoadType).show();
 } else{
  _alertMsg.html("<font style='color:blue'>√</font>").show();
 };
 
 oFReader.readAsDataURL(oFile); // 开始在后台进行读取操作。当图像文件的所有内容加载后,他们转换成一个data:URL,传递到onload回调函数中
 oFReader.onload = function (oFREvent) { //当读取操作成功完成时调用.
  document.getElementById("uploadPreview").src = oFREvent.target.result;
 };
};

运行效果及返回的图片URL展示:

传统文件上传的局限性

以上就是本文的全部内容,希望对大家的学习有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章