头图

封装Ajax

蝼蚁之行

问题:发送一次Ajax请求代码过多,发送多次请求代码冗余且重复

解决方案:将请求代码封装到函数中,发送请求时调用函数即可

1、简约版

function ajax(mether, url, callback, data, flag) {
    // 是否异步,默认异步
    flag = flag || true;
    let xhr;
    
    // 请求方法转化为大写
    mether = mether.toUpperCase();
    
    // 解决兼容新问题
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest()
    } else if (window.ActiveXObject) {
        xhr = new ActiveXObject()
    }
    
    // 响应内容
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            callback(xhr.responseText)
        }
    }
    ``
    // 如果是get请求
    if (mether === 'GET') {
        let date = new Date();
        let timer = date.getTime();
        xhr.open("GET", url + '?' + data + '&timer' + timer, flag);
        xhr.send()
    
        // 如果是post请求
    } else if (mether === 'POST') {
        xhr.open('POST', url, flag);
        xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
        xhr.send(data)
    }
}

注意:get请求中加入了时间参数,这是为了解决缓存问题

在低版本的IE浏览器中,Ajax 有严重的缓存问题。在请求地址不发生改变的情况下,只有第一次的请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果。这就导致了即使服务器的数据更新了,客户端依然拿到的依然是缓存中的旧数据

解决办法就是:在请求地址的后面请求参数,保证每一次请求中请求参数的值不同

所以每次发送都加上实时时间,这样每次的请求参数就不一样了

2、详细版

上面简约版默认是处理好数据的,即在传入时要自行处理好数据

该方法新增了请求成功和请求失败的方法

function Ajax(options) {
    // 默认参数
    let defaults = {
        method: 'GET',
        url: '',
        data: {},
        header: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        success: function() {},
        error: function() {}
    }

    // options 替换掉 defaults 中的相同属性
    Object.assign(defaults, options)
    
    // 请求方式大写
    defaults.method = defaults.method.toUpperCase()

    let xhr;
    // 解决兼容性
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        xhr = new ActiveXObject();
    }

    // 监听请求过程
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            // 获取响应头数据
            let contentType = xhr.getResponseHeader('Content-Type');
            // 获取响应数据
            let contentText = xhr.responseText;

            // 如果服务器端返回是JSON字符串的话,需要转换为JSON对象
            if (contentType === 'application/json') {
                contentText = JSON.parse(contentText)
            }

            //  当HTTP状态码为200时,调用success函数
            if (xhr.status === 200) {
                defaults.success(contentText, xhr)
                // 否则调用error函数
            } else {
                defaults.error(contentText, xhr)
            }
        }
    }

    // 拼接请求参数 namer=薛之谦&song=刚刚好
    let params = ''
    for (let key in defaults.data) {
        params += key + '=' + defaults.data[key] + '&'
    }
    // 去除最后一个字符 &
    params = params.substr(0, params.length - 1);

    // 如果是GET请求
    if (defaults.method === 'GET') {
        // 需要拼接请求地址
        defaults.url = defaults.url + '?' + params;
    }
    
    // 配置请求方式和路径
    xhr.open(defaults.method, defaults.url)

    // 如果是POST请求
    if (defaults.method === 'POST') {
        let contentType = defaults.header['Content-Type'];
        // 设置请求头
        xhr.setRequestHeader('Content-Type', contentType);
        // 如果要发送的是JSON对象,直接将JSON对象转换为json字符串 发送
        if (contentType === 'application/json') {
            xhr.send(JSON.stringify(defaults.data))
                // 如果发送的数据不是jSON对象
        } else {
            xhr.send(params)
        }

        // 如果发送的不是POST请求,那么直接发送GET请求
    } else {
        xhr.send();
    }
};

GET请求 和 POST请求最大的区别就是:数据的发送方式的不同

  • GET请求是将数据与请求地址拼接在一起
  • POST请求是将数据传给send() 发送给服务器

它们的共同点就是:数据都需要拼接成 namer=xxx&age=xxx 这种形式

不过POST请求需要设置头部:

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

若想以JSON字符串的形式发送数据,需要先将JSON对象转换为JSON字符串;并且需要使用POST请求

JSON.stringify(JSON对象)

调用封装的Ajax函数:

前提:需要先导入该函数

Ajax({
    // 请求方式
    method: 'post',
    // 请求地址
    url: 'http://localhost:3000/cache',
    // 使用JSON对象的形式发送数据
    header: {
        'Content-Type': 'application/json'
    },
    data: {
        namer: '薛之谦',
        song: '刚刚好'
    },
    success: function(data, xhr) {
        console.log('请求成功');
        console.log(data);
        console.log(xhr);
    },
    error: function(data, xhr) {
        console.log('请求失败');
        console.log(xhr);
        console.log(xhr.getResponseHeader);
    }
});
阅读 444

日益努力然后风声水起

13 声望
1 粉丝
0 条评论
你知道吗?

日益努力然后风声水起

13 声望
1 粉丝
文章目录
宣传栏