共计 3917 个字符,预计需要花费 10 分钟才能阅读完成。
旧版 XMLHttpRequest
的缺点
- 只支持文本数据的传输,无法用来读取和上传文件
- 传输和接收数据时,没有进度信息,只能提示有没有完成
XMLHttpRequest
Level2 新功能
- 可以设置 HTTP 请求的时限
- 可以使用 FormData 对象管理表单数据
- 可以上传文件
- 可以获得数据传输的进度信息
设置HTTP请求时限
有时,Ajax 操作很耗时,而且无法预知要耗费多长时间;如果用户网速很慢,可能要等很久;新版本的 XMLTttpRequest 对象,增加了 timeout
属性,可以设置 HTTP 请求的时限:
xhr.timeout = 3000
上面的语句,将最长等待时间设置为 3000 毫秒,超过了这个时限,就会自动停止 HTTP 请求;与之配套的还有一个 ontimeout
事件,用来指定回调函数:
xhr.ontimeout = function(e) {
alert('请求超时!')
}
FormData
对象管理表单数据
AJax操作往往用来提交表单数据,为了方便表单处理,HTML5新增了FormData对象,可以模拟表单操作:
// 获取表单元素
var form = document.querySelector('#form1')
// 监听表单元素的 submit 事件
form.addEventListener('submit', function (e) {
// 阻止默认提交行为
e.preventDefault()
// 根据form表单创建 FormData 对象,会自动将表单数据填充到 FormData对象中
var fd = new FormData(form)
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
})
上传文件
- 定义 UI 结构
- 验证是否选择了文件
// 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
// 获取到文件列表
var files = document.querySelector('#filel').files
if(flies.length <= 0 ) {
return alert('请选择要上传的文件')
}
// ...后续业务逻辑
})
- 向 FormData中追加文件
// 创建 FormData 对象
var fd = new FormData()
// 向 FormData 中追加文件
fd.append('avatar', files[0])
- 使用 xhr 发起带文件的请求
// 创建xhr对象
var xhr = new XMLHttpRequest()
// 调用open函数,指定请求类型与URL地址;其中请求类型必须为POST
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
// 发起请求
xhr.send(fd)
- 监听
onreadystatechange
事件
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 {
// 图片上传失败
alert('图片上传失败: '+ data.message)
}
}
}
// 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
// 获取到文件列表
var files = document.querySelector('#filel').files
if(flies.length <= 0 ) {
return alert('请选择要上传的文件')
}
// 创建 FormData 对象
var fd = new FormData()
// 向 FormData 中追加文件
fd.append('avatar', files[0])
// 创建xhr对象
var xhr = new XMLHttpRequest()
// 调用open函数,指定请求类型与URL地址;其中请求类型必须为POST
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) {
// 文件上传成功
// 将服务器返回的图片地址,设置为<img>的 src 属性
document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
} else {
// 图片上传失败
alert('图片上传失败: '+ data.message)
}
}
}
})
显示文件上传进度
新版本的 XMLHttpRequest
对象中,可以通过监听 xhr.upload.onprogress
事件,来获取到文件的上传进度
// 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 监听 xhr.upload 的 onprogress 事件
xhr.upload.onprogress = function(e) {
// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
if(e.lengthComputable) {
// e.loaded 以传输字节
// e.total 需传输的总字节
var percentComplete = Math.cell((e.loaded / e.total) * 100)
}
}
监听上传完成的事件
xhr.upload.onload = function() {
// 移除上传中的类样式
// 添加上传完成的类样式
$('#percent').removeClass().addClass('progress-bar progress-bar-success progress-bar-striped active')
}
使用 jQuery 完成文件上传
ajaxStart(callback)
Ajax请求开始时,执行 ajaxStart
函数; 可以在 ajaxStar
的callback中显示loading效果:
// 自 jQuery 版本 1.8起, 该方法只能被附加到文档上
$(document).ajaxStart(function() {
$('#loading').show()
})
$(document).ajaxStart()
函数会监听当前文档内所有的Ajax请求
ajaxStop(callback)
Ajax请求结束时,执行 ajaxStop
函数; 可以在 ajaxStar
的callback中隐藏loading效果:
// 自 jQuery 版本 1.8起, 该方法只能被附加到文档上
$(document).ajaxStop(function() {
$('#loading').hide()
})
$(function () {
// 监听到Ajax请求被发起了
$(document).ajaxStart(function () {
$('#loading').show()
})
// 监听到Ajax完成的事件
$(document).ajaxStop(function () {
$('#loading').hide()
})
$('#btnUpload').on('click', function () {
// 将 jQuery 对象转换为 DOM 对象,并获取选中文件列表
var files = $('#file')[0].files
// 判断是否选择了文件
if (files.length <= 0) {
return alert('请选择文件!')
}
// 向 FormData 中追加文件
var fd = new FormData()
fd.append('avatar', files[0])
$.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)
}
})
})
})
正文完