qiaofugui
qiaofugui
发布于 2024-05-21 / 0 阅读
0
0

Ajax-XMLHttpRequest Level2

旧版 XMLHttpRequest 的缺点

  1. 只支持文本数据的传输,无法用来读取和上传文件
  2. 传输和接收数据时,没有进度信息,只能提示有没有完成

XMLHttpRequest Level2 新功能

  1. 可以设置 HTTP 请求的时限
  2. 可以使用 FormData 对象管理表单数据
  3. 可以上传文件
  4. 可以获得数据传输的进度信息

设置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))
                }
            }
        })

上传文件

  1. 定义 UI 结构
  2. 验证是否选择了文件
// 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
    // 获取到文件列表
    var files = document.querySelector('#filel').files
    if(flies.length <= 0 ) {
        return alert('请选择要上传的文件')
    }
    // ...后续业务逻辑
})
  1. 向 FormData中追加文件
// 创建 FormData 对象
var fd = new FormData()
// 向 FormData 中追加文件
fd.append('avatar', files[0])
  1. 使用 xhr 发起带文件的请求
// 创建xhr对象 
var xhr = new XMLHttpRequest()
// 调用open函数,指定请求类型与URL地址;其中请求类型必须为POST
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
// 发起请求
xhr.send(fd)
  1. 监听 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)
            }
        })
    })
})

评论