放下Axios,手写纯原生Ajax通讯接口

前言

axios做为vue框架中最经常使用的ajax工具包之一,能够与后台API接口进行通讯,传送或接收数据,在先后端分离开发中,发挥了通讯桥梁的重要做用。vue

虽然像axios这样的第三方工具包很好用,可是这类工具包并不能很好地帮助前段开发人员,尤为是新人理解JavaScript原生的ajax通讯机制。ios

所以,本文将经过JS原生的ajax通讯实例,为读者详细介绍原生ajax通讯机制和使用方法。git

关于Ajax

1999年,微软公司发布 IE 浏览器5.0版,第一次引入新功能:容许 JavaScript 脚本向服务器发起 HTTP 请求。这个功能当时并无引发注意,直到2004年 Gmail 发布和2005年 Google Map 发布,才引发普遍重视。2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是经过 JavaScript 的异步通讯,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通讯的代名词,也就是说,只要用脚本发起通讯,就能够叫作 AJAX 通讯。W3C 也在2006年发布了它的国际标准。github

具体来讲,Ajax 包括如下几个步骤。web

  1. 建立 XMLHttpRequest
  2. 实例发出 HTTP
  3. 请求接收服务器传回的数据
  4. 更新网页数据

简单来讲,Ajax 经过原生的XMLHttpRequest对象发出 HTTP 请求,获得服务器返回的数据后,再进行处理。ajax

建立Ajax通讯接口

在这里插入图片描述
如图所示,本文将采用封装输出Axios通讯接口的方式,封装原生的Ajax通讯接口,方便读者对二者的实际应用进行对比。

1. 生成通讯接口

首先,咱们须要封装一个相似Axios的通讯接口,该接口将XMLHttpRequest对象封装在promise对象中。json

具体代码以下:axios

const ajax = function({
    // 定义接口参数
    method = 'GET', // 请求方式:get, post, put, delete 
    url = '', // 请求链接
    data = null, // post data
    params = null, // get params
    baseURL = '', // domain URL
    withCredentials = false // api验证请求
} = {}) {
    const promise = new Promise(function(resolve, reject) {
        // api url
        let apiUrl = baseURL + url;
        // create get params
        if (params) {
            let urlParams = [];
            for (let key in params) {
                urlParams.push(`${key}=${params[key]}`)
            }
            apiUrl += `?${urlParams.join('&&')}`;
        }
        // access
        const accessHandler = function() {
            // readState === 4, 表示api接口请求完成
            if (this.readyState !== 4) {
                return;
            }
            // 根据status状态码进行相关操做
            if (this.status === 200) {
                resolve(JSON.parse(this.response));
            } else {
                reject(new Error(this.statusText));
            }
        };
        // error
        const errorHandler = function() {
            console.error(this.statusText);
        };
        // timeout
        const timeoutHandler = function() {
            console.error(`The request for ${apiUrl} timed out.`);
        };
        // client
        const client = new XMLHttpRequest(); // 生成XMLHttpRequest实例对象
        client.open(method, apiUrl, true); // 配置client参数
        // status
        client.onreadystatechange = accessHandler; // 请求成功
        client.ontimeout = timeoutHandler; // 请求超时 
        client.onerror = errorHandler; // 请求错误
        // config
        client.responseType = "json"; // 返回值:json
        client.timeout = 10 * 1000; // 超时时间:10s
        client.withCredentials = withCredentials; // 设置验证
        client.setRequestHeader("Accept", "application/json"); // 设置请求头
        // send
        client.send(data); // 发生请求

    });

    return promise; // 输出promise对象
};

export { ajax }
复制代码

2. 封装通讯接口

将原生Ajax接口其进行封装,方便在vue项目中使用。后端

具体代码以下:api

// 配置API接口地址
const root = ''

// 引入原生Ajax
import { ajax } from './ajax'

// 自定义判断元素类型JS
function toType(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

// 参数过滤函数
function filterNull(params) {
    for (let key in params) {
        if (params[key] === null) {
            delete params[key]
        }
        if (toType(params[key]) === 'string') {
            params[key] = params[key].trim()
        } else if (toType(params[key]) === 'object') {
            params[key] = filterNull(params[key])
        } else if (toType(params[key]) === 'array') {
            params[key] = filterNull(params[key])
        }
    }
    return params
}

// 封装Ajax接口

function apiAjax(method, url, params, success, failure) {
    if (params) {
        params = filterNull(params)
    }
    ajax({
            method: method,
            url: url,
            data: method === 'POST' || method === 'PUT' ? params : null,
            params: method === 'GET' || method === 'DELETE' ? params : null,
            baseURL: root,
            withCredentials: false
        })
        .then(function(res) {
            if (success) {
                success(res)
            }
        })
        .catch(function(err) {
            if (failure) {
                failure(err)
            } else {
                throw err;
            }
        })
}

// 返回在vue模板中的调用接口
export default {
    get: function(url, params, success, failure) {
        return apiAjax('GET', url, params, success, failure)
    },
    post: function(url, params, success, failure) {
        return apiAjax('POST', url, params, success, failure)
    },
    put: function(url, params, success, failure) {
        return apiAjax('PUT', url, params, success, failure)
    },
    delete: function(url, params, success, failure) {
        return apiAjax('DELETE', url, params, success, failure)
    }
}
复制代码

调用Ajax通讯接口

完成Ajax接口封装后,在main.js文件中直接引入。

import ajaxApi from './api/ajaxApi'

Vue.prototype.$ajaxApi = ajaxApi
复制代码

最后,在vue页面进行使用。

created() {
    this.getDataFromApi();
  },
  data() {
    return {
      tableData: []
    };
  },
  methods: {
    getDataFromApi() {
      this.$ajaxApi.get(
        "/data/tableData", // mock 数据接口
        null,
        Response => {
          this.tableData = Response;
          console.log(Response);
        },
        Error => {
          throw Error;
        }
      );
    }
  }
复制代码

具体效果以下图。

在这里插入图片描述
在这里插入图片描述

总结

相信经过本文,你对原生ajax通讯已经有了必定的了解。须要提醒的是,本文实例是本人根据mock数据接口编写的,所以,在通用性上面,可能有所不足。若是你想直接使用本文实例,可能须要根据你实际调用的接口进行调整。

固然,你也能够直接访问本人的github项目,项目地址:github.com/jiangjiahen…

最后,祝工做顺利,生活愉快。

在这里插入图片描述
相关文章
相关标签/搜索