文件上传
# 文件上传
# 1. 上传文件
# 1. 定义 UI 结构
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传按钮 -->
<button id="btnUpload">上传文件</button>
<!-- 3. 显示上传到服务器上的图片 -->
<img src="" alt="" id="img" width="800" />
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. 验证是否选择了文件
// 1. 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload');
// 2. 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
// 3. 获取到选择的文件列表
var files = document.querySelector('#file1').files;
// 4. 验证是否选择了文件
if (files.length <= 0) {
return alert('请选择要上传的文件!');
}
// 文件选择正常,调用文件上传函数
uploadFile(files[0]);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3. 向 FormData
中追加文件
function uploadFile(file) {
// 1. 创建 FormData 对象
var fd = new FormData();
// 2. 向 FormData 中追加文件
fd.append('avatar', file);
// 3. 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
// 4. 设置请求的 URL 和请求方式
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar', true);
// 5. 监听请求状态改变事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
if (data.status === 200) { // 上传文件成功
// 将服务器返回的图片地址,设置为 <img> 标签的 src 属性
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url;
} else { // 上传文件失败
console.error('上传失败:', data.message);
}
}
};
// 6. 发送请求
xhr.send(fd);
}
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
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
FormData
对象:用于封装文件数据和其他表单数据。fd.append()
:将文件添加到FormData
对象中,avatar
是字段名,file
是实际的文件对象。xhr.open()
:配置请求的类型和 URL 地址,true
表示异步请求。xhr.send()
:发送请求,fd
是要发送的表单数据。
# 2. 显示文件上传进度
# 1. 导入需要的库
<link rel="stylesheet" href="./lib/bootstrap.css" />
<script src="./lib/jquery.js"></script>
1
2
2
# 2. 基于 Bootstrap 渲染进度条
<!-- 进度条 -->
<div class="progress" style="width: 500px; margin: 10px 0;">
<div class="progress-bar progress-bar-info progress-bar-striped active" id="percent" style="width: 0%">
0%
</div>
</div>
1
2
3
4
5
6
2
3
4
5
6
# 3. 监听上传进度的事件
function uploadFile(file) {
var fd = new FormData();
fd.append('avatar', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar', true);
// 监听上传进度事件
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
// 计算上传进度的百分比
var percentComplete = Math.ceil((e.loaded / e.total) * 100);
// 更新进度条的宽度和显示百分比
$('#percent')
.attr('style', 'width:' + percentComplete + '%')
.html(percentComplete + '%');
}
};
// 监听上传完成的事件
xhr.upload.onload = function() {
$('#percent')
.removeClass('progress-bar-info progress-bar-striped active') // 移除上传中的样式
.addClass('progress-bar-success'); // 添加上传成功的样式
};
// 监听请求状态改变事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
if (data.status === 200) {
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url;
} else {
console.error('上传失败:', data.message);
}
}
};
xhr.send(fd);
}
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
40
41
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
40
41
xhr.upload.onprogress
:监听文件上传进度事件,e.loaded
是已上传的字节数,e.total
是总字节数。percentComplete
:计算上传进度百分比,并更新进度条。xhr.upload.onload
:上传完成后的事件处理,通常会更新进度条样式以表示上传成功。
# 3. jQuery 实现文件上传
# 1. 定义 UI 结构
<!-- 导入 jQuery -->
<script src="./lib/jquery.js"></script>
<!-- 文件选择框 -->
<input type="file" id="file1" />
<!-- 上传文件按钮 -->
<button id="btnUpload">上传</button>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. 验证是否选择了文件
// 为上传按钮绑定点击事件
$('#btnUpload').on('click', function() {
// 1. 获取文件选择框的文件列表
var files = $('#file1')[0].files;
// 2. 验证是否选择了文件
if (files.length <= 0) {
return alert('请选择图片后再上传!');
}
// 选择了文件,调用文件上传函数
uploadFile(files[0]);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
$('#file1')[0].files
:将 jQuery 对象转换为原生 DOM 对象,从而访问文件列表。
# 3. 向 FormData
中追加文件
function uploadFile(file) {
// 1. 创建 FormData 对象
var fd = new FormData();
// 2. 向 FormData 中追加文件
fd.append('avatar', file);
// 3. 发起文件上传请求
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
// 4. 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
contentType: false,
// 5. 不对 FormData 中的数据进行 URL 编码,保持数据原样
processData: false,
success: function(res) {
console.log('文件上传成功:', res);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('文件上传失败:', textStatus, errorThrown);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fd.append('avatar', file)
:将选择的文件添加到FormData
对象中,avatar
是字段名,file
是实际的文件对象。contentType: false
:告知 jQuery 不要设置Content-Type
,让浏览器根据FormData
自动设置。processData: false
:告诉 jQuery 不要对FormData
对象进行 URL 编码。
# 4. jQuery 实现 loading 效果
# 1. ajaxStart(callback)
// 在所有 Ajax 请求开始时,显示 loading 效果
$(document).ajaxStart(function() {
$('#loading').show();
});
1
2
3
4
2
3
4
$(document).ajaxStart()
:绑定一个函数,当任何 Ajax 请求开始时,该函数会被调用。$('#loading').show()
:显示一个用于表示 loading 状态的元素,通常是一个加载动画。
# 2. ajaxStop(callback)
// 在所有 Ajax 请求结束时,隐藏 loading 效果
$(document).ajaxStop(function() {
$('#loading').hide();
});
1
2
3
4
2
3
4
$(document).ajaxStop()
:绑定一个函数,当所有 Ajax 请求完成时,该函数会被调用。$('#loading').hide()
:隐藏 loading 元素,停止显示加载动画。
# 3. 综合示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传示例</title>
<link rel="stylesheet" href="./lib/bootstrap.css" />
<script src="./lib/jquery.js"></script>
<style>
#loading {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 10px;
background: rgba(0, 0, 0, 0.8);
color: white;
font-size: 16px;
}
</style>
</head>
<body>
<!-- 文件选择框 -->
<input type="file" id="file1" />
<!-- 上传文件按钮 -->
<button id="btnUpload">上传</button>
<!-- 显示上传到服务器上的图片 -->
<img src="" alt="" id="img" width="800" />
<!-- Loading 效果 -->
<div id="loading">上传中,请稍等...</div>
<script>
// 文件上传函数
function uploadFile(file) {
var fd = new FormData();
fd.append('avatar', file);
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
contentType: false,
processData: false,
success: function(res) {
console.log('文件上传成功:', res);
$('#img').attr('src', 'http://www.liulongbin.top:3006' + res.url);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('文件上传失败:', textStatus, errorThrown);
}
});
}
// 显示 loading 效果
$(document).ajaxStart(function() {
$('#loading').show();
});
// 隐藏 loading 效果
$(document).ajaxStop(function() {
$('#loading').hide();
});
// 上传按钮点击事件
$('#btnUpload').on('click', function() {
var files = $('#file1')[0].files;
if (files.length <= 0) {
return alert('请选择图片后再上传!');
}
uploadFile(files[0]);
});
</script>
</body>
</html>
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08