一、使用xhr实现文件上传功能
实现步骤:定义UI结构 → 验证用户是否选择了文件 → 向FornData中追加文件 → 使用xhr发起上传文件的请求 → 监听onreadyStatechange事件
1、定义UI结构
<!--1. 文件选择框 -->
<input type="file" id="file1">
<!-- 2. 上传文件按钮 -->
<button id="btnUpload">上传文件</button><br />
<!-- 3.img标签用来显示上传成功以后的图片 -->
<img src="" id="img" width="800">
2、验证用户是否选择了文件
// 1.获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload');
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click',function(){
// 3.获取到选择的文件列表
var files = document.querySelector("#file1").files;
if(files.length<=0){
return alert ('请选择要上传的文件');
}
})
3、向FormData中追加文件
// 1.创建formdata对象
var fd = new FormData();
// 2.向formdata中追加文件
fd.append("avatar",files[0])
4、使用xhr发起上传文件的请求
// 1.创建xhr
var xhr = new XMLHttpRequest();
// 2.创建请求
xhr.open("POST",'http://www.liulongbin.top:3006/api/upload/avator');
// 3.发起请求
xhr.send(fd);
5、监听onreadyStatechange事件
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.log('图片上传失败!' + data.message)
}
}
}
二、xhr案例(实现文件带进度条上传)
1、基于Bootstrap绘制进度条效果
Bootstrap进度条地址:https://v3.bootcss.com/components/#progress
<!-- 引入Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- bootstrap 中的进度条 -->
<div class="progress" style="width: 500px; margin: 15px 10px;">
<div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
0%
</div>
</div>
2、动态设置进度条
基于jQuery操作DOM,调用attr属性设置style样式
引入jQuery
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
// 监听文件上传的进度
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
// 计算出上传的进度
var procentComplete = Math.ceil((e.loaded / e.total) * 100)
console.log(procentComplete)
// 动态设置进度条
$('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
}
}
3、监听上传完成的事件
xhr.upload.onload = function () {
// removeClass():移除上传中的类样式;addClass()添加上传完成的类样式
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 引入bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- 引入jQuery -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<!-- bootstrap 中的进度条 -->
<div class="progress" style="width: 500px; margin: 15px 10px;">
<div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
0%
</div>
</div>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />
<script>
// 1. 获取到文件上传按钮
var btnUpload = document.querySelector('#btnUpload')
// 2. 为按钮绑定单击事件处理函数
btnUpload.addEventListener('click', function () {
// 3. 获取到用户选择的文件列表
var files = document.querySelector('#file1').files
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
var fd = new FormData()
// 将用户选择的文件,添加到 FormData 中
fd.append('avatar', files[0])
var xhr = new XMLHttpRequest()
// 监听文件上传的进度
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
// 计算出上传的进度
var procentComplete = Math.ceil((e.loaded / e.total) * 100)
console.log(procentComplete)
// 动态设置进度条
$('#percent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
}
}
xhr.upload.onload = function () {
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
xhr.send(fd)
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.log('图片上传失败!' + data.message)
}
}
}
})
</script>
</body>
</html>
运行结果
二、使用jQuery实现文件上传功能
实现步骤:定义UI结构 → 验证用户是否选择了文件 → 向FornData中追加文件 → 使用jQuery发起上传文件的请求
1、定义UI结构
<!-- 引入jQuery -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<!-- 文件选择框 -->
<input type="file" id="file1" />
<button id="btnUpload">上传文件</button>
<br />
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2Fd590c78cda71722a604c44b80e79c7392eed11edd280-S5faVN_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1668831485&t=ad1842680bf433c15ba9b8ced946a2bd" alt="" style="display: none;" id="loading" />
2、验证用户是否选择了文件
$('#btnUpload').on('click', function () {
var files = $('#file1')[0].files
if (files.length <= 0) {
return alert('请选择文件后再上传!')
}
})
3、向FornData中追加文件
var fd = new FormData();
fd.append('avatar', files[0]);
4、使用jQuery发起上传文件的请求
使用jQuery上传文件,固定写法:contentType: false, processData: false,
contentType: false:不修改Content-Type属性,使用FormData默认的Content-Type值
processData: false:不对FormData中的数据进行url编码,而是将FormData数据原样发送到服务器
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
// 不修改Content-Type属性,使用FormData默认的Content-Type值
contentType: false,
// 不对FormData中的数据进行url编码,而是将FormData数据原样发送到服务器
processData: false,
success: function (res) {
console.log(res)
}
})
四、jQuery案例(实现文件带loading效果上传)
1、通过ajaxStart(callback)展示loading效果
ajaxStart(callback)
:Ajax请求开始
时,执行ajaxStart()函数,可以在ajaxStart的回调函数中显示loading效果
注意点
① 从jQuery1.8版本起,ajaxStart()只能被附加在document身上,不能添加到body身上
② $(document).ajaxStart()
函数会监听当前文档内所有的Ajax请求
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
$('#loading').show()
})
2、通过ajaxStop(callback)隐藏loading效果
ajaxStop(callback)
:Ajax请求结束
时,执行ajaxStop()函数,可以在ajaxStop的回调函数中隐藏loading效果
// 监听到 Ajax 完成的事件
$(document).ajaxStop(function () {
$('#loading').hide()
})
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 引入jQuery -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<input type="file" id="file1" />
<button id="btnUpload">上传文件</button>
<br />
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2Fd590c78cda71722a604c44b80e79c7392eed11edd280-S5faVN_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1668831485&t=ad1842680bf433c15ba9b8ced946a2bd" alt="" style="display: none;" id="loading" />
<script>
$(function () {
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
$('#loading').show()
})
// 监听到 Ajax 完成的事件
$(document).ajaxStop(function () {
$('#loading').hide()
})
$('#btnUpload').on('click', function () {
var files = $('#file1')[0].files
if (files.length <= 0) {
return alert('请选择文件后再上传!')
}
var fd = new FormData()
fd.append('avatar', files[0])
// 发起 jQuery 的 Ajax 请求,上传文件
$.ajax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
processData: false,
contentType: false,
success: function (res) {
console.log(res)
}
})
})
})
</script>
</body>
</html>