使用jQuery异步上传文件的方法

使用jQuery异步上传文件的方法

技术背景

在Web开发中,文件上传是一个常见的需求。传统的表单提交会导致页面刷新,影响用户体验。而异步文件上传可以在不刷新页面的情况下完成文件上传,提升用户体验。借助HTML5的FormDataFile API,结合jQuery的$.ajax()方法,可以轻松实现异步文件上传。

实现步骤

HTML5支持下的异步文件上传

  1. HTML部分:创建包含文件输入框和上传按钮的表单,以及用于显示上传进度的progress元素。
1
2
3
4
5
<form enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<progress></progress>
  1. JavaScript部分:对文件进行验证,并使用$.ajax()方法提交表单数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 文件验证
$(':file').on('change', function () {
var file = this.files[0];
if (file.size > 1024) {
alert('max upload size is 1k');
}
// Also see .name, .type
});

// 按钮点击事件
$(':button').on('click', function () {
$.ajax({
// 服务器脚本处理上传
url: 'upload.php',
type: 'POST',
// 表单数据
data: new FormData($('form')[0]),
// 告诉jQuery不要处理数据或担心内容类型
cache: false,
contentType: false,
processData: false,
// 自定义XMLHttpRequest
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// 处理上传进度
myXhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
$('progress').attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
});
});

HTML5不支持时的回退方案(隐藏iframe技术)

  1. HTML部分:创建表单并将其目标设置为隐藏的iframe。
1
2
3
4
5
<form target="iframe" action="" method="post" enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<iframe name="iframe" id="iframe" style="display:none"></iframe>
  1. JavaScript部分:可以通过监听iframe的onLoad事件来处理上传结果。但在Chrome中,需要使用cookie来模拟onLoad事件。

使用插件实现异步文件上传

jQuery File Upload插件为例:

  1. 安装插件:在项目中添加jquery.ui.widget.jsjquery.iframe-transport.jsjquery.fileupload.js
  2. HTML部分:创建文件输入框。
1
<input id="upload" name="upload" type="file" />
  1. JavaScript部分:编写上传文件的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function uploadFile(element) {
$(element).fileupload({
dataType: 'json',
url: '../DocumentUpload/upload',
autoUpload: true,
add: function (e, data) {
// 选择文件时的处理代码
data.formData = {
files: data.files[0]
};
data.submit();
},
done: function (e, data) {
// 文件上传后
},
progress: function (e, data) {
// 上传进度
},
fail: function (e, data) {
// 上传失败
},
stop: function () {
// 取消操作
}
});
}

$(document).ready(function() {
uploadFile($('#upload'));
});
  1. 服务器端处理:编写MVC控制器和操作来处理文件上传。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class DocumentUploadController : Controller
{
[System.Web.Mvc.HttpPost]
public JsonResult upload(ICollection<HttpPostedFileBase> files)
{
bool result = false;
if (files != null || files.Count > 0)
{
try
{
foreach (HttpPostedFileBase file in files)
{
if (file.ContentLength == 0)
throw new Exception("Zero length file!");
else
// 保存文件的代码
}
}
catch (Exception)
{
result = false;
}
}
return new JsonResult()
{
Data = result
};
}
}

核心代码

使用$.ajax()方法上传文件

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
url: 'file/destination.html',
type: 'POST',
data: new FormData($('#formWithFiles')[0]),
processData: false,
contentType: false
}).done(function(){
console.log("Success: Files sent!");
}).fail(function(){
console.log("An error occurred, the files couldn't be sent!");
});

隐藏iframe技术上传文件

1
2
3
4
5
<form target="iframe" action="" method="post" enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<iframe name="iframe" id="iframe" style="display:none"></iframe>

使用jQuery File Upload插件上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function uploadFile(element) {
$(element).fileupload({
dataType: 'json',
url: '../DocumentUpload/upload',
autoUpload: true,
add: function (e, data) {
data.formData = {
files: data.files[0]
};
data.submit();
},
done: function (e, data) {
// 文件上传后
},
progress: function (e, data) {
// 上传进度
},
fail: function (e, data) {
// 上传失败
},
stop: function () {
// 取消操作
}
});
}

$(document).ready(function() {
uploadFile($('#upload'));
});

最佳实践

  • 文件验证:在上传文件之前,对文件的名称、大小和MIME类型进行验证,避免上传不符合要求的文件。
  • 进度条显示:使用HTML5的progress元素或自定义的进度条来显示文件上传的进度,提升用户体验。
  • 兼容性处理:考虑不同浏览器的兼容性,对于不支持HTML5的浏览器,使用隐藏iframe技术作为回退方案。
  • 错误处理:在$.ajax()方法中添加fail回调函数,处理文件上传过程中可能出现的错误。

常见问题

浏览器兼容性问题

HTML5的File API在一些旧版本的浏览器(如IE 9及以下)中不被支持。可以使用隐藏iframe技术或插件来解决兼容性问题。

服务器端处理问题

服务器端需要正确处理文件上传请求,确保文件能够正确保存到指定的位置。同时,需要处理文件上传过程中可能出现的错误,如文件大小超过限制、文件类型不允许等。

跨域问题

如果文件上传的目标服务器与当前页面的域名不同,可能会遇到跨域问题。可以通过设置服务器端的CORS(跨域资源共享)来解决跨域问题。


使用jQuery异步上传文件的方法
https://119291.xyz/posts/2025-05-12.jquery-asynchronous-file-upload-methods/
作者
ww
发布于
2025年5月12日
许可协议