乐趣区

关于javascript:ajax和fetch封装网络请求

fetch

  1. 默认不带 cookie
  2. 谬误不会 reject
  3. HTTP 谬误(例如 404 Page Not Found 或 500 Internal Server Error)不会导致 Fetch 返回的 Promise 标记为 reject;.catch() 也不会被执行。
  4. 想要准确的判断 fetch 是否胜利,须要蕴含 promise resolved 的状况,此时再判断 response.ok 是不是为 true

// 不反对间接设置超时, 能够用 promise
function fetchTimeout(url, init, timeout = 3000) {

return new Promise((resolve, reject) => {fetch(url, init)
        .then(resolve)
        .catch(reject);
    setTimeout(reject, timeout);
})

}
// 停止 fetch
const controller = new AbortController();

fetch(

    'http://domain/service', {
        method: 'GET',
        signal: controller.signal
    })
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.error('Error:', error));

controller.abort();

interface IOptions {
    url: string;
    type?: string;
    data: any;
    timeout?: number;
}

function formatUrl(json) {let dataArr = [];
    json.t = Math.random();
    for (let key in json) {dataArr.push(`${key}=${encodeURIComponent(json[key])}`)
    }
    return dataArr.join('&');
}

export function ajax(options: IOptions) {return new Promise((resolve, reject) => {if (!options.url) return;

        options.type = options.type || 'GET';
        options.data = options.data || {};
        options.timeout = options.timeout || 10000;
    
        let dataToUrlstr = formatUrl(options.data);
        let timer;
    
        // 1. 创立
        let xhr;
        if ((window as any).XMLHttpRequest) {xhr = new XMLHttpRequest();
        } else {xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
    
        if (options.type.toUpperCase() === 'GET') {
            // 2. 连贯
            xhr.open('get', `${options.url}?${dataToUrlstr}`, true);
            // 3. 发送
            xhr.send();} else if (options.type.toUpperCase() === 'POST') {
            // 2. 连贯
            xhr.open('post', options.url, true);
            xhr.setRequestHeader('ContentType', 'application/x-www-form-urlencoded');
            // 3. 发送
            xhr.send(options.data);
        }
    
        // 4. 接管
        xhr.onreadystatechange = () => {if (xhr.readyState === 4) {clearTimeout(timer);
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {resolve(xhr.responseText);
                } else {reject(xhr.status);
                }
            }
        }
    
        if (options.timeout) {timer = setTimeout(() => {xhr.abort();
                reject('超时');
            }, options.timeout)
        }

        // xhr.timeout = options.timeout;
        // xhr.ontimeout = () => {//     reject('超时');
        // }
    });
}
退出移动版