Ajax上传多文件

逻辑逐风使
• 阅读 12604

AJAX的采用标志着的Web历史上的一个巨大飞跃。与Web服务器通信而不需要重新加载页面的能力已改变了Web应用程序构建。动态网站的概念形成以后,AJAX(XMLHttpRequests) 技术发展迅速。
近年来XMLHttpRequests增加了一个很好的功能来处理文件上传。传统上,许多开发者用其他技术如Flash上传文件到服务器。这种方法的问题是,用户需要安装第三方浏览器插件的。
在这篇文章中你会学到如何用JavaScript技术将文件上传到服务器。我们将教你一个请求上传多文件的例子。然而,你可以用同样的办法上传单个文件。
让我们开始吧!

选择要上传的文件

你需要做的第一件事就是建立你的HTML表单让用户选择文件。让事情简单,我们用标准的<input>元素并设为file类型。

<form id="file-form" action="handler.php" method="POST">
  <input type="file" id="file-select" name="photos[]" multiple/>
  <button type="submit" id="upload-button">Upload</button>
</form>

请注意,<input>元素有个multiple属性。这将允许用户通过浏览器文件选择器选择多个文件。如果你不指定此属性的用户只能选择一个文件。
现在你的HTML表格建好了,我们再看看处理文件上传的JavaScript代码。

上传文件到服务器

首先你需要创建三个变量来获取HTML里的<form><input><button>元素。

var form = document.getElementById('file-form');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');

下一步你需要绑定一个事件监听器到表单的onsubmit事件。

form.onsubmit = function(event) {
  event.preventDefault();

  // 更新按钮里的文字
  uploadButton.innerHTML = 'Uploading...';

  // 其余的代码将在这里...
}

在事件监听器里,首先调用event对象的preventDefault()。这将阻止浏览器提交的表单,使我们能够继续处理Ajax文件上传。
下一步,更新的uploadButtoninnerHTML属性为Uploading...,这告诉用户文件上传中。
接下来,从<input>元素中获取[FileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList)内容并存储到变量里。你可以通过访问files属性来做到这点。

// 获取选择的文件
var files = fileSelect.files;

然后创建一个新的[FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData)对象。这是用来接收Ajax请求获取的键/值对数据。

// 创建一个FormData对象
var formData = new FormData();

然后,通过循环获取files数组的每一个文件内容,并将它们添加到你刚才创建的formData对象里。你也许还想检查用户选的文件是否是你规定的文件类型。

// 对每个文件进行循环处理
for (var i = 0; i < files.length; i++) {
  var file = files[i];

  // 检查文件类型
  if (!file.type.match('image.*')) {
    continue;
  }

  // 添加文件到formData
  formData.append('photos[]', file, file.name);
}

在这里,你先读取当files数组里的所有文件,然后检查以确保它是图像。该文件的type属性将返回一个字符串的文件类型。你可以使用JavaScript的 match()方法来确保这个字符串匹配所需的类型。如果文件类型不匹配,通过调用continue跳过后面的语句结束本轮循环。
然后使用append()方法把文件添加到formData对象里。


注:

FormData.append()方法用于处理FilesBlobs,或Strings

// Files
formData.append(name, file, filename);

// Blobs
formData.append(name, blob, filename);

// Strings
formData.append(name, value);    

第一个参数指定数据项的name。这将形成数据的key。第二个参数指定一个FileBlob或者 String作为数据数据的value。当添加一个FileBlob,可以指定一个filename文件名,但这不是必需的。


下一步你需要设置XMLHttpRequest与服务器通信。你首先需要创建一个新的XMLHttpRequest对象。

// 设置请求。
var xhr = new XMLHttpRequest();

现在您需要创建一个新连接到服务器。你使用open方法。该方法带三个参数。HTTP的请求方式、url和一个布尔值(确定是否应处理异步请求)。

// 打开连接。
xhr.open('POST', 'handler.php', true);

下一步你需要建立一个事件侦听器,onLoad事件完成后就会触发时。xhr对象的status属性会告诉你请求是否成功完成。

// 请求完成时建立一个处理程序。
xhr.onload = function () {
  if (xhr.status === 200) {
    // File(s) uploaded.
    uploadButton.innerHTML = 'Upload';
  } else {
    alert('An error occurred!');
  }
};

剩下要做的是发送请求。用xhrsend方法发送formData

// 发送数据。
xhr.send(formData);

这就是开始使用Ajax文件上传的内容。您的服务器端代码需要提取文件并处理。

浏览器的支持

浏览器支持总体上是好的。Internet Explorer是唯一的例外。IE 10及以上的版本支持,但早期版本的IE不支持本文提到的一些XMLHttpRequest功能。

IE FIREFOX CHROME SAFARI OPERA
10.0+ 4.0+ 7.0+ 5+ 12+

总结

在这篇文章中你学到了如何上传文件使用本地JavaScript技术,Web服务器。在功能方面的进步,消除XMLHttpRequests供开发者使用第三方浏览器插件来处理文件上传的需要。这是很好的为本地的浏览器功能往往是更快和更比一个插件提供的安全。
你计划在你的项目中使用Ajax上传的文件?请在下面的评论中分享你的想法。


英文原文
本文地址

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
待兔 待兔
11个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
3年前
Java多线程导致的的一个事物性问题
业务场景我们现在有一个类似于文件上传的功能,各个子站点接受业务,业务上传文件,各个子站点的文件需要提交到总站点保存,文件是按批次提交到总站点的,也就是说,一个批次下面约有几百个文件。      考虑到白天提交这么多文件会影响到子站点其他系统带宽,我们将分站点的文件提交到总站点这个操作过程独立出来,放到晚上来做,具体时间是晚上7:00到早上7:00。
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
小白学大数据 小白学大数据
3个月前
Scrapy结合Selenium实现滚动翻页数据采集
引言在当今的互联网数据采集领域,许多网站采用动态加载技术(如AJAX、无限滚动)来优化用户体验。传统的基于Requests或Scrapy的爬虫难以直接获取动态渲染的数据,而Selenium可以模拟浏览器行为,实现滚动翻页和动态内容加载。本文将介绍如何结合S