前言
- 做web开发,我们都知道浏览器通过
XMLHttpRequest
对象进行http通信 - 在实际开发中我们使用的是各种框架封装了的
XMLHttpRequest
对象,对具体实现往往一知半解.所以为了换框架好上手,请求有异常好调试,有必要深入学习一下XMLHttpRequest
- 本文从基础
XMLHttpRequest
开始,一步步把它封装为更实用的框架级别
实例
- 一个最简单的http请求
let xhr = new XMLHttpRequest(); xhr.open('GET', '/url', true); xhr.send();
- 一个稍微完整的http请求
let xhr = new XMLHttpRequest(); // 请求成功回调函数 xhr.onload = e => { console.log('request success'); }; // 请求结束 xhr.onloadend = e => { console.log('request loadend'); }; // 请求出错 xhr.onerror = e => { console.log('request error'); }; // 请求超时 xhr.ontimeout = e => { console.log('request timeout'); }; // 请求回调函数.XMLHttpRequest标准又分为Level 1和Level 2,这是Level 1和的回调处理方式 // xhr.onreadystatechange = () => { // if (xhr.readyState !== 4) { // return; // } // const status = xhr.status; // if ((status >= 200 && status < 300) || status === 304) { // console.log('request success'); // } else { // console.log('request error'); // } // }; xhr.timeout = 0; // 设置超时时间,0表示永不超时 // 初始化请求 xhr.open('GET/POST/DELETE/...', '/url', true || false); // 设置期望的返回数据类型 'json' 'text' 'document' ... xhr.responseType = ''; // 设置请求头 xhr.setRequestHeader('', ''); // 发送请求 xhr.send(null || new FormData || 'a=1&b=2' || 'json字符串');
- 很多东西一看就懂,但当真正去用的时候就会发现很多问题
- 为了深入学习,本着使XMLHttpRequest更易用的原则,模仿jQuery ajax封装
XMLHttpRequest
封装XMLHttpRequest
const http = { /** * js封装ajax请求 * >>使用new XMLHttpRequest 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不支持XMLHttpRequest) * >>使用es6语法,如果需要在正式环境使用,则可以用babel转换为es5语法 https://babeljs.cn/docs/setup/#installation * @param settings 请求参数模仿jQuery ajax * 调用该方法,data参数需要和请求头Content-Type对应 * Content-Type data 描述 * application/x-www-form-urlencoded 'name=哈哈&age=12'或{name:'哈哈',age:12} 查询字符串,用&分割 * application/json name=哈哈&age=12' json字符串 * multipart/form-data new FormData() FormData对象,当为FormData类型,不要手动设置Content-Type * 注意:请求参数如果包含日期类型.是否能请求成功需要后台接口配合 */ ajax: (settings = {}) => { // 初始化请求参数 let _s = Object.assign({ url: '', // string type: 'GET', // string 'GET' 'POST' 'DELETE' dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ... async: true, // boolean true:异步请求 false:同步请求 required data: null, // any 请求参数,data需要和请求头Content-Type对应 headers: {}, // object 请求头 timeout: 1000, // string 超时时间:0表示不设置超时 beforeSend: (xhr) => { }, success: (result, status, xhr) => { }, error: (xhr, status, error) => { }, complete: (xhr, status) => { } }, settings); // 参数验证 if (!_s.url || !_s.type || !_s.dataType || _s.async === undefined) { alert('参数有误'); return; } // 创建XMLHttpRequest请求对象 let xhr = new XMLHttpRequest(); // 请求开始回调函数 xhr.addEventListener('loadstart', e => { _s.beforeSend(xhr); }); // 请求成功回调函数 xhr.addEventListener('load', e => { const status = xhr.status; if ((status >= 200 && status < 300) || status === 304) { let result; if (xhr.responseType === 'text') { result = xhr.responseText; } else if (xhr.responseType === 'document') { result = xhr.responseXML; } else { result = xhr.response; } // 注意:状态码200表示请求发送/接受成功,不表示业务处理成功 _s.success(result, status, xhr); } else { _s.error(xhr, status, e); } }); // 请求结束 xhr.addEventListener('loadend', e => { _s.complete(xhr, xhr.status); }