在之前無(wú)論是iOS氛赐、Android開發(fā)魂爪,還是后來(lái)的flutter開發(fā)時(shí)網(wǎng)絡(luò)請(qǐng)求類都是需要我們自己做一層封裝的,如果不封裝那么我們會(huì)面臨幾個(gè)不便:
- 請(qǐng)求頭每次網(wǎng)絡(luò)請(qǐng)求都要單獨(dú)設(shè)置
- 返回?cái)?shù)據(jù)的正確性判斷每次都要重復(fù)大量代碼
- 返回?cái)?shù)據(jù)格式有變化需要修改所有網(wǎng)絡(luò)請(qǐng)求的地方
針對(duì)這些問(wèn)題我簡(jiǎn)單做了一下封裝艰管,大概解決了以上三個(gè)問(wèn)題
一滓侍、首先在項(xiàng)目根目錄新建文件夾libs
,然后文件夾中新建netRequest.js
import Vue from 'vue'
//靜態(tài)資源們
const baseInfo = {
//網(wǎng)絡(luò)請(qǐng)求的地址
baseUrl: 你自己的網(wǎng)絡(luò)baseUrl,
//網(wǎng)絡(luò)請(qǐng)求錯(cuò)誤的統(tǒng)一報(bào)錯(cuò)
netWrong: '請(qǐng)檢查網(wǎng)絡(luò)',
}
//網(wǎng)絡(luò)請(qǐng)求對(duì)象
export const netRequest = {
//登錄成功時(shí)將獲取的token通過(guò)這個(gè)key存儲(chǔ)起來(lái)牲芋,以后取值也是使用這個(gè)key
tokenKey: 'tokenKey',
//登錄地址
requestLoginProcessAction: baseInfo.baseUrl+'/a/wws/ssys/lg',
//請(qǐng)求方式GET\POST
method: {
'GET':'GET',
'POST':'POST'
},
//不同接口編碼格式不同撩笆,根據(jù)不同接口設(shè)置編碼格式
contentType: {
'json':'application/json;charset=UTF-8',
'urlencoded':'application/x-www-form-urlencoded'
},
getHeaders: function(type){
//如果不設(shè)置Content-Type那么默認(rèn)為application/json;charset=UTF-8
var cType = 'application/json;charset=UTF-8';
if(type){//以設(shè)置的Content-Type為準(zhǔn)
cType = type;
}
let _headers = {
"os": "ios",
"version": "1.0.0",
"appname": "QQ",
"Content-Type": cType
};
//如果當(dāng)前已經(jīng)登錄,那么在請(qǐng)求頭設(shè)置token缸浦,否則不設(shè)置token
const token = uni.getStorageSync(netRequest.tokenKey);
if(token){
console.log('token='+token);
Vue.set(_headers,'cookie',token)
//也可以使用Object.assign方式實(shí)現(xiàn)動(dòng)態(tài)添加屬性
// _headers = Object.assign({},_headers,{'cookie':token})
}else{
console.log('token為空');
}
return _headers;
},
//處理網(wǎng)絡(luò)請(qǐng)求返回的數(shù)據(jù)夕冲,如果成功則返回解析的數(shù)據(jù),如果不成功則返回錯(cuò)誤信息
isSucc: function(response,succ,fail){
if(response){
if(response.statusCode===200){
if(response.data.statusCode===200){
if(succ && typeof(succ)=='function'){
succ(response.data.data)
}
}else if(response.data.statusCode===401){//用戶未登錄裂逐,token超時(shí)
//登錄超時(shí)歹鱼,一般需要彈出登錄頁(yè)面,讓用戶重新登錄
}else if(response.data.statusCode===600){//版本升級(jí)
uni.showModal({
title:'版本升級(jí)',
content:'您有新版本可以使用',
confirmText:'升級(jí)',
confirmColor:'#007AFF',
cancelText:'放棄',
cancelColor:'#999999',
success(res) {
if(res.confirm){
//點(diǎn)擊升級(jí)按鈕
}else if(res.cancel){
//點(diǎn)擊放棄升級(jí)
}
}
})
}else{//本次網(wǎng)絡(luò)成功請(qǐng)求到服務(wù)器卜高,但是服務(wù)器返回的不是定義好的狀態(tài)碼
if(fail && typeof(fail)=='function'){
fail(response.data.message)
}
}
}else{//本次網(wǎng)絡(luò)失敗
if(fail && typeof(fail)=='function'){
fail(response.errMsg)
}
}
}else{//獲取的response為空
if(fail && typeof(fail)=='function'){
fail(baseInfo.netWrong)
}
}
}
}
二弥姻、將netRequest
掛載到vue對(duì)象的屬性上
在main.js
文件中
import {netRequest} from './libs/netRequest.js'
Vue.prototype.$netRequest = netRequest
這樣我們就不需要每個(gè)頁(yè)面都引入一下
三、使用
let _this = this
uni.request({
header:_this.$netRequest.getHeaders(_this.$netRequest.contentType.urlencoded),
url:_this.$netRequest.requestLoginProcessAction,
data:{'username':'zhangjing','password':'123456'},
method:_this.$netRequest.method.POST,
success(res) {
//請(qǐng)求成功掺涛,對(duì)獲取的response數(shù)據(jù)進(jìn)行處理
_this.$netRequest.isSucc(res,function(data){
//本次網(wǎng)絡(luò)請(qǐng)求成功庭敦,獲取處理好之后可以使用的數(shù)據(jù)
},function(errStr){
//本次網(wǎng)絡(luò)請(qǐng)求成功,但是數(shù)據(jù)有問(wèn)題薪缆,例如密碼錯(cuò)誤
uni.showToast({
title: errStr,
icon:'none',
duration:3000
});
})
},
fail(res) {
//本次網(wǎng)絡(luò)請(qǐng)求失敗了秧廉,沒有請(qǐng)求到服務(wù)器
},
complete() {
//本次網(wǎng)絡(luò)請(qǐng)求完成了,無(wú)論成功還是失敗都會(huì)調(diào)用
}
})
??這里需要注意_this
,在網(wǎng)絡(luò)請(qǐng)求的success
定血、fail
赔癌、complete
使用this獲取的不是本頁(yè)的上下文