第 40 题(如何实现一个 ajax())
主要使用以下文件
config.js:ajax 请求配置核心文件
loading.js:element-ui 请求加载动画
index.js:二次封装 config.js 请求并导出该方法,配置请求拦截器、响应拦截器
index.vue:调用 ajax 的示例页面
注意:推荐在 api 目录统一管理所有接口,如果遇到报错请调整正确引用路径
config.js
import loading from './loading.js';
// 加载动画类const animation = false;
// 接口加载动画
const intTimer = 10;
// 接口请求超时时间(秒)class Config {
constructor(data) {
this.method = data.method;
this.url = data.url;
this.param = data.param || {};
this.header = data.header || {};
this.interceptors = data.interceptors;
this.response = data.response;
return this.filter();
}// 创建XHR对象
createXHR() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} else {
// code for IE6, IE5
return new ActiveXObject('Microsoft.XMLHTTP');
}
}// HTTP请求
xhrRequest(header, method, url, param, async, interceptors, response) {
return new Promise(resolve => {
var xhr = this.createXHR();
if (animation == true) {
loading.requestStart();
// 执行动画
}// 请求拦截
if (interceptors({ header, method, url: this.url, param: this.param, async })) {
xhr.open(method, url, async);
xhr.timeout = 1000 * intTimer;
//设置xhr请求的超时时间
Object.keys(header).map(key => {
xhr.setRequestHeader(key, header[key]);
});
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;
application/json;
charset=utf-8');
xhr.send(param);
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
loading.requestEnd();
// 结束动画
try {
let data = https://www.it610.com/article/JSON.parse(xhr.responseText);
resolve(response(data, { header, method, url: this.url, param: this.param, async }));
} catch (error) {
console.log('接口返回没有任何信息!');
resolve(false);
}
} else {
return 'request is unsucessful ' + xhr.status;
}
};
} else {
console.error('request interceptor', '请求未发出, 请求拦截器已生效!');
}// 请求超时方法
xhr.ontimeout = function(e) {
console.log('接口请求超时!');
loading.requestEnd();
// 结束动画
};
// 请求错误方法
xhr.onerror = function(e) {
console.log('接口请求失败');
loading.requestEnd();
// 结束动画
};
});
}// 参数转换
convParams(param) {
let mark = '?';
let hasMark = this.url.indexOf(mark) > 0;
// 是否包含特殊字符
if (hasMark) {
mark = '&';
}let newParams = '';
let i = 0;
for (let key in param) {
if (i > 0) {
newParams += `&${key}=${param[key]}`;
} else {
newParams += `${mark}${key}=${param[key]}`;
}
i++;
}
return newParams;
}// 数据GET、POST请求处理
filter() {
let obj = {
header: this.header,
method: this.method,
url: this.url,
param: {},
async: true,
interceptors: this.interceptors,
response: this.response
};
// 接口名称拼接位置:(1、url) (2、param)let newParams = this.convParams(this.param);
if (this.method == 'GET') {
obj.url += newParams;
} else {
newParams = newParams.replace('?', '');
obj.param = newParams;
}return this.xhrRequest(obj.header, obj.method, obj.url, obj.param, obj.async, obj.interceptors, obj.response);
}
}export default Config;
【第 40 题(如何实现一个 ajax())】loading.js
import { Loading } from 'element-ui';
class animation {
constructor() {
this.needLoadingRequestCount = 0;
this.loading
}/**
* 动画开始
*/
requestStart() {
if (this.needLoadingRequestCount === 0) {
this.loading = Loading.service({
lock: true,
text: 'loading...',
background: 'rgba(0, 0, 0, 0.7)'
});
}
this.needLoadingRequestCount++;
}/**
* 动画结束
*/
requestEnd() {
if (this.needLoadingRequestCount <= 0) return;
this.needLoadingRequestCount--;
if (this.needLoadingRequestCount === 0) {
this.loading.close();
}
}
}export default new animation()
index.js
import Config from './config.js';
/**
* 接口请求方法
* @func request
* @param {Object} method 请求方式: 仅支持GET、POST
* @param {String} url 请求地址
* @param {Object} param 请求参数
*/
let request = option => {
// 配置默认请求参数return new Config({
header: {
Authorization: 'APPCODE edc39cc1dc5f4c139498322115b99e51'
},
method: option.method,
url: option.url,
param: option.param,
interceptors: interceptors,
response: response
});
};
/**
* 请求拦截器
* @func interceptors
*/
let interceptors = config => {
return true;
};
/**
* 响应拦截器
* @func response
*/
let response = (data, config) => {
let res;
// 处理返回格式
if (data.res) {
res = data.res;
} else if (data.data) {
res = data.data;
} else {
res = data;
}
return res;
};
export default request;
index.vue
文章的内容/灵感都从下方内容中借鉴
- 【持续维护/更新 500+前端面试题/笔记】https://github.com/noxussj/In...
- 【大数据可视化图表插件】https://www.npmjs.com/package...
- 【利用 THREE.JS 实现 3D 城市建模(珠海市)】https://3d.noxussj.top/
推荐阅读
- 第6.2章(设置属性)
- parallels|parallels desktop 解决网络初始化失败问题
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 第三节|第三节 快乐和幸福(12)
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- android第三方框架(五)ButterKnife
- 开学第一天(下)
- 野营记-第五章|野营记-第五章 讨伐梦魇兽
- 2018年11月19日|2018年11月19日 星期一 亲子日记第144篇
- 第326天