React和ReactNative 的网络请求使用的是fetch
关于基本的POST和GET请求以及异步变同步就不再描述,看看API的介绍。
网络请求封装要完成的内容有:
1、基本功能(网络请求)
2、统一处理
异常处理
不同错误码处理
3、可定制loading弹窗提示
4 、可定制Header
5、超时处理
6、登陆验证token处理
7、url 特殊字符处理
8、网络请求日志打印
超级方便的调试技巧
const WrapFetch = (url, req, config) => {
//默认参数
let request = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + (window.token || '')
}
};
//配置参数
//默认不显示进度条,如果需要显示config传参{ showLoading: true}
const cnf = Object.assign({}, {
showLoading: false,
showLoginView: true
}, config);
//默认header,如果需要特殊处理可通过传参改变
if (req && req.headers) {
const mergeHeader = Object.assign({}, request.headers, req.headers);
request.headers = mergeHeader;
delete req.headers;
}
//merge
const merge = Object.assign({}, request, req);
//去掉url中可能存在的//
url = url.replace(/([^:])\/\//, '$1/');
if (__DEV__) {
console.log('请求->', url, '\n', JSON.stringify(merge, null, 2));
}
return new Promise((resolve, reject) => {
let isServerOk = true;
let httpStatus = 200;
//超时优化
let httpTimeout = setTimeout(() => {
const err = {
code: 'S-000002',
message: '网络超时'
};
//计时开始,显示弹窗
if (cnf.showLoading) {
msg.emit('ModalLoading:hide');
}
msg.emit('app:tip', err.code + '-' + err.message);
reject(err);
}, 5000);
//如果配置showLoading为true,显示modalloading
if (cnf.showLoading) {
msg.emit('ModalLoading:show');
}
fetch(url, merge)
.then(res => {
//清除网络超时
clearTimeout(httpTimeout);
//当前的http的状态
httpStatus = res.status;
//判断server是不是异常状态404,500等
isServerOk = !!(res.status >= 200 && res.status < 300);
//promise
return res.json();
})
.then((res) => {
//hide
if (cnf.showLoading) {
msg.emit('ModalLoading:hide');
}
if (isServerOk&&res.code===1000) {
if (__DEV__) {
console.info('响应->', httpStatus, url, '\n', res);
}
//数据正确返回
resolve(res);
} else {
if (__DEV__) {
console.info('响应->', url, httpStatus, '\n', res);
}
if (httpStatus == 401) {
if(cnf.showLoginView){
msg.emit('tokenInvalid');
}
//token过期或者校验错误,将token清除
AsyncStorage.setItem('token', '');
window.token = '';
} else {
if (res.code === 'N-000001') {
// 系统异常隐藏
msg.emit('app:tip', '您的网络不给力:(');
} else {
msg.emit('app:tip', res.message);
}
}
reject(res);
}
})
.catch((err) => {
//清除网络超时
clearTimeout(httpTimeout);
if (cnf.showLoading) {
msg.emit('ModalLoading:hide');
}
if (__DEV__) {
console.info('WrapFetchError:', err);
}
msg.emit('app:tip', '您的网络不给力:(');
reject({
code: 'N-000001',
message: '网络错误'
});
})
.done();
});
};
export default WrapFetch;
msg.emit()是iflux-native框架的事件方法,用于调用相关方法
具体实现需要根据后端定义的接口状态码,使其符合你的项目。
作者:TaooLee 发表于2017/9/11 14:28:24 原文链接
阅读:208 评论:0 查看评论