AJAX

119 阅读1分钟

前情提要

1. open()接受三个参数:method、url、boolean
2. send()如果方法是post,接受一个body参数 && 只能放字符串或二进制数据
3. onreadystatechange用来监听通信状态的变化。可以透过readyState来知道目前进行到哪一步,包括以下几个值:
    0:init             xhr对象刚刚创建
    1:open             xhr已经open了
    2:sent             xhr已经send了
    3:receiving        服务器发送过来的数据已经接受了(head)
    4:completed        服务器发送过来的数据已经接受了(body)
4. done代表的是请求的过程完成了,完成分为成功和失败,可以透过status判断是否成功
5. 给服务器发送数据,可以是:
    i.body
    ii.querystring( ?a=1b=2 )
    iii.headers
6. 给服务器发送数据,headers一定是放在open之后,send之前
7. 服务器默认的content-type是text/plain,如果是纯文本之外的格式,要额外添加:
    xhr.setRequestHeader('content-type', 'application/json; charset=utf-8');

MINE

数据类型

主类型/子类型
text/plain
text/html
text/javascript
text/css

image/jpeg
image/gif
image/png

'get'代码实现

// 创建
let xhr = new XMLHttpRequest();

// 连接
xhr.open('get', url)

// 发送
xhr.send()

// 接受
xhr.onreadystatechagne = function() {
    if(xhr.readyState === xhr.DONE) {
        if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            xhr.responseText;
        }
    }
}

'post'代码实现

const xhr = new XMLHttpRequest();

xhr.open('post', url, true);

xhr.setRequestHeader('content-type', 'application/json; charset=utf-8');

const data = {
    username: 'admin',
    password: 'admin123'
};

xhr.send(JSON.stringify(data));

xhr.onreadystatechange = function() {
    const {readyState, status, DONE} = xhr;
    if(readyState === DONE) {
        if(status >= 200 && status < 300 || status === 304) {
            console.log(xhr.responseText)
        } else {
            console.log(xhr.responseText)
        }
    }
}

封装AJAX

思路:
1.把请求封装到一个函数里
2.使用 async function + promise 实现
2.什么东西需要抽离出来?
    - method
    - url
    - headers
    - body
    把上面要传入的数据都当参数太麻烦了,可以直接写在一个json里,好处是json是无序的
// request.js
function request(options) {
    if(typeof options === 'string') {
        options = {
            url: options,
            method: 'get'
        }
    }
    return new Promise((resolve, reject) => {
        const {
            method='get',
            url,
            headers={},
            body
        } = options;
        const xhr = new XMLHttpRequest();

        xhr.open(method, request.baseURL+url, true);

        const _headers = {...request.defaultHeaders, ...headers};
        for(let key in _headers) {
            xhr.setRequestHeader(key, _headers[key])
        }

        // body
        switch(typeof body) {
            case 'string':
                xhr.setRequestHeader('content-type', 'text/plain; charset=utf-8');
                xhr.send(body);
                break;
            case 'object':
                xhr.setRequestHeader('content-type', 'application/json; charset=utf-8');
                xhr.send(JSON.stringify(body));
                break;
            case 'undefined':
                xhr.send();
                break;
            default:
                xhr.setRequestHeader('content-type', 'text/plain; charset=utf-8');
                xhr.send(body.toString());
        }

        xhr.onreadystatechange = function() {
            const { readyState, status, DONE } = xhr;
            if(readyState === DONE) {
                if(status >= 200 && status < 300 || status === 304) {
                    resolve(xhr.responseText)
                } else {
                    reject(xhr.responseText)
                }
            }
        }
    })
}

request.defaultHeaders = {};
request.baseURL = '';