原生js简单实现ajax请求

2,774 阅读2分钟

前言

作为前端开发,向服务端发起请求这是必不可少的一个步骤,通过请求,服务端端返回给我们相应的数据,根据数据我们做出相应的操作。一般来说,现在很多前端开发者发起请求时都是采用第三方库来实现,比如axios、jQuery库等等。

利用原生JavaScript实现ajax请求

XMLHttpRequest对象

原利用一个XMLHttpRequest的对象进行后台与服务端数据的交换,目前所有浏览器都支持XMLHttpRequest,具体代码可参考如下:

function initOption(options) {
    options.type = options.type.toUpperCase() || 'GET';
    options.async = options.async || true;
    options.data = options.data || {};
    options.dataType = options.dataType || 'JSON';
    options.timeout = options.timeout || 10000;
    options.complete = options.complete || function(){};
    options.success = options.success || function(){};
    options.error = options.error || function(){};
    return options
}
function formatParams(data) {
    if (typeof data === 'object') {
        const arr = [];
        for (var key in data) {
            arr.push(key + "=" + data[key]);
        }
        return arr.join("&");
    }
    return data;
}
function ajaxXhr(url, options = {}) {
    // 初始化参数, 添加默认值
    options = initOption(options)
    // 初始化异步对象
    const xhr = new XMLHttpRequest();
    // 参数处理
    const data = formatParams(options.data);
    // 需要判断get和post
    if (options.type === 'GET') {
        // 打开请求,如果url已经有参数了,直接追加,没有从问号开始拼接
        if (url.indexOf('?') !== -1) {
            xhr.open(options.type, url + '&' + data);
        } else {
            xhr.open(options.type, url + '?' + data);
        }
        xhr.send();
    }
    if (options.type === 'POST') {
        xhr.open(options.type, url);
        // 设置请求头
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.send(data);
    }
    xhr.onreadystatechange = function() {
        // readyState五个状态 
        // 0:未初始化(Uninitialized)。尚未调用 open()方法。
        // 1:已打开(Open)。已调用 open()方法,尚未调用 send()方法。
        // 2:已发送(Sent)。已调用 send()方法,尚未收到响应。
        // 3:接收中(Receiving)。已经收到部分响应。
        // 4:完成(Complete)。已经收到所有响应,可以使用了。
        if (xhr.readyState === 4) {
            options.complete();
            if (xhr.status === 200) {
                options.success(xhr.responseText);
            } else {
                options.error(xhr, xhr.status, xhr.statusText);
            }
        }
    }
}
              
方 法描 述
abort()停止当前请求
getAllResponseHeaders()把HTTP请求的所有响应首部作为键/值对返回
getResponseHeader("header")返回指定首部的串值
open("method","URL",[asyncFlag],["userName"],["password"])建立对服务器的调用。method参数可以是GET、POST或PUT。url参数可以是相对URL或绝对URL。这个方法还包括3个可选的参数,是否异步,用户名,密码
send(content)向服务器发送请求
setRequestHeader("header", "value")把指定首部设置为所提供的值。在设置任何首部之前必须先调用open()。设置header并和请求一起发送 ('post'方法一定要 )

fetch

Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

function initOption(options) {
    options.type = options.type.toUpperCase() || 'GET';
    options.headers = options.headers || {};
    options.data = options.data || {};
    options.mode = options.mode || 'cors';
    options.credentials = options.credentials || 'manual';
    options.cache = options.cache || 'default';
    return options
}
 function formatParams(data) {
    if (typeof data === 'object') {
        const arr = [];
        for (var key in data) {
            arr.push(key + "=" + data[key]);
        }
        return arr.join("&");
    }
    return data;
}  
function ajaxFetch(url, options) {
        // 初始化参数, 添加默认值
        options = initOption(options)  
        // 参数处理
        const data = formatParams(options.data);
        let fetchBody = null
        if (options.type === 'GET') {
            if (url.indexOf('?') !== -1) {
                url = `${url}&${data}`
            } else {
                url = `${url}?${data}`
            }
        }
        if (options.type === 'POST') {
            fetchBody = data
        }
        fetch(url, Object.assign({ body: fetchBody }, options)).then((res) => {
            console.log('res', res)
        }).catch((err) => {
            console.log('err', err)
        })
    } 

参考文档

《JavaScript高级程序设计(第4版)》

使用 Fetch()