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: { 'Content-Type': "application/json" }, // 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) { 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); }); // 请求出错 xhr.addEventListener('error', e => { _s.error(xhr, xhr.status, e); }); // 请求超时 xhr.addEventListener('timeout', e => { _s.error(xhr, 408, e); }); let useUrlParam = false; let sType = _s.type.toUpperCase(); // 如果是"简单"请求,则把data参数组装在url上 if (sType === 'GET' || sType === 'DELETE') { useUrlParam = true; _s.url += http.getUrlParam(_s.url, _s.data); } // 初始化请求 xhr.open(_s.type, _s.url, _s.async); // 设置期望的返回数据类型 xhr.responseType = _s.dataType; // 设置请求头 for (const key of Object.keys(_s.headers)) { xhr.setRequestHeader(key, _s.headers[key]); } // 设置超时时间 if (_s.async && _s.timeout) { xhr.timeout = _s.timeout; } // 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应 xhr.send(useUrlParam ? null : http.getQueryData(_s.data)); }, // 把参数data转为url查询参数 getUrlParam: (url, data) => { if (!data) { return ''; } let paramsStr = data instanceof Object ? http.getQueryString(data) : data; return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr; }, // 获取ajax请求参数 getQueryData: (data) => { if (!data) { return null; } if (typeof data === 'string') { return data; } if (data instanceof FormData) { return data; } return http.getQueryString(data); }, // 把对象转为查询字符串 getQueryString: (data) => { let paramsArr = []; if (data instanceof Object) { Object.keys(data).forEach(key => { let val = data[key]; // todo 参数Date类型需要根据后台api酌情处理 if (val instanceof Date) { // val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss'); } paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); }); } return paramsArr.join('&'); } }