封装自己的Ajax函数

简介: 封装自己的Ajax函数

  要实现的效果

定义一个名为itheima的ajax函数,导入js文件之后,可以进行调用文件内的相关函数。

定义options参数选项

itheima()函数是我们自定义的Ajax函数,它接受一个配置对象作为参数,配置对象中可以配置如下属性:

  • method 请求的类型
  • url 请求的URL地址
  • data 请求携带的数据
  • success 请求成功之后的回调函数

  处理data参数

需要把data对象,转化成查询字符串的格式,从而提交给服务器,因此提前定义resolveData函数如下:

function resolveData(data) {
    var arr = [];
    for (const k in data) {
        //这里说一下对象的调用方法,对象调用可以使用【】和点,这里的对象调用需要用【】的,k是字符串,点后面不能是字符串,所以不能直接data.k,
        //我们可以先进行字符串链接data.k再使用eval方法进行解析,就可以使用点调用了
        // var str = k + '=' + eval("data." + k);
        var str = k + '=' + data[k];
        arr.push(str);
    }
    return arr.join('&')
}
var str = resolveData({ name: 'xiaoxie', age: 20 });
console.log(str);

  定义itheima函数

在itheima()函数中,需要创建xhr对象,并监听onreadystatechange事件。

function itheima(options) {
    let xhr = new XMLHttpRequest();
    let qs = resolveData(options.data)
--------判断类型 发起请求 代码--------------
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
         let result = JSON.parse(xhr.responseText)
            options.success(result)
        }
    }
}

  判断请求的类型

不同的请求类型,对应的xhr对象的不同操作,因此需要对请求类型进行if…else…的判断。

if (options.method.toUpperCase() === 'GET') {
       xhr.open('get', options.URL + '?' + qs)
        xhr.send();
   } else if (options.method.toUpperCase() === 'POST') {
       xhr.open('post', options.URL)
       xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
       xhr.send(qs);
   }

xhr level2的新特性

  旧版xhr的缺点

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

  xhr levle2的新特性

  • 可以设置http请求的时限。
  • 可以使用formdata对象管理表单数据
  • 可以上传文件
  • 可以获得数据传输的进度信息。

    设置http请求时限。

有时,Ajax操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久,新版本的xhr对象,增加了timeout属性,可以设置http请求的时限:

xhr.timeout = 3000

上面的语句,将最长等待时间设为3000毫秒,过了这个时限,就自动停止http请求。与之配套的还有一个timeout事件,用来指定回调函数。

xhr.ontimeout = function(event){
alert('请求超时')
}
let xhr = new XMLHttpRequest();
       xhr.timeout = 30;
       xhr.ontimeout = function () {
           console.log(请求超时);
       }
       xhr.open('get', 'http://liulongbin.top:3006/api/getbooks')
       xhr.send()
       xhr.onreadystatechange = function () {
           if (xhr.readyState === 4 && xhr.status == 200) {
               console.log(xhr.responseText);
           }
       }

    FormData对象管理表单数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作。

let fd = new FormData();
        fd.append('uname', 'xiaoxie')
        fd.append('pwd', 123456)
        let 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));
            }
        }

FormData对象也可以用来获取网页表单的值,不用通过serialize()方法转换,可以获取值后可以直接使用,不用通过示例代码如下:

var form = document.querySelector('#form1')
        form.addEventListener('submit', function (e) {
            e.preventDefault();
            //创建对象,获取数据。
            let fd = new FormData(form);
            let 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));
                }
            }
        })

    上传文件

新版xhr对象,不仅可以发送文本信息,还可以上传文件。

  1. 定义ui结构
  2. 验证是否选择了文件
  3. 向FormData中追加文件
  4. 使用xhr发起上传文件的请求
  5. 监听onreadystatechange事件
    定义UI结构
<!-- 文件选择框 -->
    <input type="file" id="file1">
    <!-- 上传文件的按钮 -->
    <button id="btnUpload"></button>
    <br>
    <img src="" alt="" id="img" width="800">

验证是否选择了文件

//获取文件上传按钮
        let btn = document.getElementsByTagName('button')[0];
        //为按钮绑定单击事件处理函数
        btn.addEventListener('click', function () {
            //获取用户选择的文件鼠标
            let files = document.querySelector('#file1').files;
            if (files.length <= 0) {
                return alert('请选择要上传的文件')
            }
            console.log('用户选择了待上传的文件');
        })

向FormData中追加文件

let fd = new FormData()
  fd.append('avatar', files[0])

使用xhr发起上传文件的请求

let xhr = new XMLHttpRequest();
            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) {
                    let data = JSON.parse(xhr.responseText)
                    if (data.status === 200) {
                        //上传成功
                        alert('上传成功')
                        document.getElementById('img').src = 'http://www.liulongbin.top:3006' + data.url
                    } else {
                        console.log('图片上传失败' + data.message);
                    }
                }
            }

显示文件上传进度

新版本的XHR对象中,可以通过监听xhr.upload.onprogress事件,来获取到文件的上传进度,语法格式如下:

//监听上传进度
            xhr.upload.onprogress = function (e) {
                if (e.lengthComputable) {
                    let uploadProgroess = Math.ceil((e.loaded / e.total) * 100)
                    console.log(uploadProgroess);
                }
            }

美化进度显示

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
        integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
 //设置进度条
$('#percent').attr('style', 'width:' + uploadProgroess).html(uploadProgroess + '%')

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
        integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
    <!-- 文件选择框 -->
    <input type="file" id="file1">
    <!-- 上传文件的按钮 -->
    <button id="btnUpload">上传文件</button>
    <br>
    <img src="" alt="" id="img" width="800">
    <div class="progress" style="width: 300px;">
        <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
            0%
        </div>
    </div>
    <script>
        //获取文件上传按钮
        let btn = document.getElementsByTagName('button')[0];
        //为按钮绑定单击事件处理函数
        btn.addEventListener('click', function () {
            //获取用户选择的文件属性,是一个数组。
            let files = document.querySelector('#file1').files;
            if (files.length <= 0) {
                return alert('请选择要上传的文件')
            }
            //表单中添加相应的数据
            let fd = new FormData()
            fd.append('tupian', files[0])
            //使用xhr发起上传文件的请求
            let xhr = new XMLHttpRequest();
            //监听上传进度
            xhr.upload.onprogress = function (e) {
                if (e.lengthComputable) {
                    let uploadProgroess = Math.ceil((e.loaded / e.total) * 100)
                    console.log(uploadProgroess);
                    //设置进度条
                    $('#percent').attr('style', 'width:' + uploadProgroess).html(uploadProgroess + '%')
                }
            }
            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) {
                    let data = JSON.parse(xhr.responseText)
                    if (data.status === 200) {
                        //上传成功
                        alert('上传成功')
                        document.getElementById('img').src = 'http://www.liulongbin.top:3006' + data.url
                    } else {
                        console.log('图片上传失败' + data.message);
                    }
                }
            }
        })
    </script>
</body>
</html>


目录
相关文章
|
4月前
|
前端开发
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
|
4月前
|
前端开发 API
用promise封装ajax
用promise封装ajax
36 0
|
10月前
|
前端开发 JavaScript API
Promise封装Ajax请求
Promise封装Ajax请求
44 0
|
10月前
|
JSON 前端开发 JavaScript
jQuery Ajax请求成功后,为什么一直在error函数里
jQuery Ajax请求成功后,为什么一直在error函数里
|
12月前
|
前端开发 JavaScript
js - 封装ajax
简单封装/使用promise封装ajax/封装:$.ajax()
|
小程序 前端开发
|
前端开发 JavaScript
uniapp中简单封装ajax
uniapp中简单封装ajax
168 0
|
前端开发
ajax 通过move_uploaded_file函数上传图片获取$_FILES['file']对象的属性内容
ajax 通过move_uploaded_file函数上传图片获取$_FILES['file']对象的属性内容
47 0
|
前端开发
封装ajax请求接口
封装ajax请求接口
102 0
|
前端开发
ES6 从入门到精通 # 18:使用 Promise 封装 ajax
ES6 从入门到精通 # 18:使用 Promise 封装 ajax
122 0
ES6 从入门到精通 # 18:使用 Promise 封装 ajax