理解XMLHttpRequest

1,284 阅读3分钟

从回调函数开始说起...

回调函数(作为参数传递给另外一个函数的函数)
  • 同步回调(回调函数在主函数返回之前执行的过程)

let callback = function(){
    console.log('i am do homework')
}
function doWork(cb) {
    console.log('start do work')
    cb()
    console.log('end do work')
}
doWork(callback)

  • 异步回调(回调函数在主函数外部执行的过程)

let callback = function(){
    console.log('i am do homework')
}
function doWork(cb) {
    console.log('start do work')
    setTimeout(cb,1000)   
    console.log('end do work')
}
doWork(callback)
  • 把异步函数做成一个任务,用来添加到消息队列尾部来实现
  • 把异步函数添加到微任务队列中,在当前任务末尾执行

系统调用栈(事件循环系统在执行一个任务的时候,需要为这个任务维护一个系统调用栈)

XMLHttpRequest
  • 工作流程(XMLHttpRequest 发起请求,是由浏览器的其他进程或者线程去执行,然后再将执行结果利用 IPC 的方式通知渲染进程,之后渲染进程再将对应的消息添加到消息队列中)
  1. 创建xhr对象,用来执行实际的网络请求
  2. 为xhr对象注册相应的回调函数
    1. ontimeout - 处理请求超时后的操作
    2. onerror - 处理请求出错后的操作
    3. onreadystatechange - 监控后台请求过程中的状态,比如可以监控到 HTTP 头加载完成的消息、HTTP 响应体消息以及数据加载完成的消息
  3. 用xhr.open() 打开请求
    1. method - 请求方法
    2. url - 请求url
    3. async - 是否异步
    4. user - 请求认证<可选>
    5. password - 请求认证<可选>
  4. 配置基础的请求信息
    1. timeout - 请求超时时间
    2. responseType - 数据返回类型,默认text
  5. 用xhr.send() 发送请求

  • 浏览器安全策略引入的问题
    • 跨域()
    • HTTPS 混合内容(HTTPS 混合内容是 HTTPS 页面中包含了不符合 HTTPS 安全要求的内容,比如包含了 HTTP 资源,通过 HTTP 加载的图像、视频、样式表、脚本等)

var apiStr = 'https://api.apiopen.top/searchMusic?name=一生有你'
function httpRquestFunc(optObj) {
    /* 1、创建xhr对象 */
    let xhr = new XMLHttpRequest();

    /* 2、为xhr对象注册http状态变化回调函数 */
    xhr.onreadystatechange = function(){
        var statusNum = xhr.readyState;
        switch(statusNum){
            case 0:/* 代理被创建,但尚未调用 open() 方法 */
                console.log(statusNum);
            break;
            case 1:/* open() 方法已经被调用 */
                console.log(statusNum);
            break;
            case 2:/* send() 方法已经被调用,并且头部和状态已经可获得 */
                console.log(statusNum);
            break;
            case 3:/* 下载中; responseText 属性已经包含部分数据 */
                console.log(statusNum);
            break;
            case 4:/* 下载操作已完成 */
                console.log(xhr.status);/* http状态码 */
                if(xhr.status === 200 || xhr.status === 304){/* 成功或者浏览器有缓存 */
                    document.getElementById('main_div').innerHTML = xhr.response;
                }
            break;
        }
    }

    /* 3、为xhr对象注册请求超时回调函数 */
    xhr.ontimeout = function(){
        alert('请求超时了');
    }

    /* 4、为xhr对象注册报错回调函数 */
    xhr.onerror = function() {
        console.log(xhr);
    }

    /* 
        5、打开请求
        method - 请求方法
        url - 请求url
        async - 是否异步
        user - 请求认证
        password - 请求认证
    */
    xhr.open(optObj.method,optObj.url);

    /* 6、配置参数 */
    xhr.timeout = optObj.timeout || 120000;
    xhr.responseType = optObj.resType || "text";

    /*
        7、发送请求 
        ArrayBufferView - 
        ArrayBuffer - 
        Blob - 
        FormData - 
        null - method为GET
    */
    xhr.send(null);
    // xhr.send('string');
    // xhr.send(new Blob());
    // xhr.send(new Int8Array());
    // xhr.send({ form: 'data' });
    // xhr.send(document);
}
httpRquestFunc({
    url:apiStr,/* url */
    method:'GET',/* 请求方法 */
    timeout:10000,/* 超时时间 */
});