1. 普通网络请求
1.1 未封装前index.vue页面使用
getMachineNum:function(){
var timestamp = Date.parse(new Date());//时间戳
var token = uni.getStorageSync(_self.sessionKey);
var device = "wxapp";
var ver = "1.1.30";
uni.request({
url: this.siteBaseUrl + 'machine/index',
method: 'GET',
data: {
token : token,
timestamp : timestamp,
device : device,
ver : ver
},
success: res => {
console.log("getMachineNum success:" + JSON.stringify(res));
if (res.data.code == "-1") {//登录失效
uni.showToast({
title: res.data.msg,
mask: false,
duration: 1500
});
} else if (res.data.code == "0") {
var data = res.data.data;
_self.onlineNum = data.onlineNum;
_self.machineNum = data.machineNum;
}else {
console.log("未处理的结果码");
}
},
fail: (e) => {
console.log("getMachineNum fail:" + JSON.stringify(e));
},
complete: () => {}
});
},
请求结果
{
"data": {
"code": "0",
"msg": "success",
"data": {
"machineNum": 124,
"onlineNum": 1,
}
},
"header": {
"Server": "nginx/1.14.0",
"Date": "Thu, 11 Apr 2019 03:08:20 GMT",
"Content-Type": "application/json;charset=utf-8;",
"Transfer-Encoding": "chunked",
"Connection": "keep-alive",
"X-Powered-By": "PHP/7.1.16"
},
"statusCode": 200,
"cookies": [],
"errMsg": "request:ok"
}
1.2 main.js中封装网络请求
- main.js
Vue.prototype.sendRequest= function(param,backpage, backtype){
var _self = this,
url = param.url,
data = param.data || {},
header = param.header,
token = "";
//拼接完整请求地址
var requestUrl = this.siteBaseUrl + url;
//固定参数
if(!data.token){//如果参数中无token(除了小程序第一次通过code获取token的接口默认参数token = login,其他接口token参数都是在本地缓存中获取)
token = uni.getStorageSync(this.sessionKey);
if(!token){//本地无token需重新登录
_self.login(backpage, backtype);
return;
}else{
data.token = token;
}
}
var timestamp = Date.parse(new Date());//时间戳
data["timestamp"] = timestamp;
data["device"] = "wxapp";//data["device"] = "iosapp";
data["ver"] = "1.1.30";//data["ver"] = "1.0.0";
//GET或POST
if(param.method){
param.method = param.method.toUpperCase();//小写改为大写
}
//网络请求
uni.request({
url: requestUrl,
method: param.method || "GET",
header: header || {'content-type' : "application/json"},
data: data,
success: res => {
console.log("网络请求success:" + JSON.stringify(res));
if (res.statusCode && res.statusCode != 200) {//api错误
uni.showModal({
content:"" + res.errMsg
});
return;
}
if (res.data.code) {//返回结果码code判断:0成功,1错误,-1未登录
if (res.data.code == "-1") {
_self.login(backpage, backtype);
return;
}
if (res.data.code != "0") {
uni.showModal({
showCancel:false,
content:"" + res.data.msg
});
return;
}
} else{
uni.showModal({
showCancel:false,
content:"" + res.data.msg
});
return;
}
typeof param.success == "function" && param.success(res.data);
},
fail: (e) => {
console.log("网络请求fail:" + JSON.stringify(e));
uni.showModal({
content:"" + res.errMsg
});
typeof param.fail == "function" && param.fail(res.data);
},
complete: () => {
console.log("网络请求complete");
uni.hideLoading();
typeof param.complete == "function" && param.complete(res.data);
return;
}
});
}
Vue.prototype.login = function(backpage, backtype){
var _self = this;
uni.login({
success:function(res){
_self.requestData({
url : "user/login",
data : {
code : res.code,
token : "login"
},
success : function(res2){
if (res2.data.errCode == "0") {//用户存在:存储token
uni.setStorageSync(_self.sessionKey,res2.data.token);
} else if (res2.data.errCode == "0") {//用户不存在:调转到绑定页面
uni.redirectTo({url:'../binding/binding?backpage='+backpage+'&backtype='+backtype});
return false;
}
}
},backpage, backtype)
},
fail:function(e){
console.log("微信login接口调用失败:" + JSON.stringify(e));
}
});
return;
}
Vue.prototype.siteBaseUrl = 'https://api.uchat.com.cn/';
Vue.prototype.sessionKey = "sess_jk";
- 封装后index.vue页面get请求调用
getMachineNum:function(){
this.sendRequest({
url : "machine/index",
success : function(res){
console.log("getMachineNum success:" + JSON.stringify(res));
var data = res.data;
_self.onlineNum = data.onlineNum || 0;
_self.machineNum = data.machineNum || 0;
},
fail:function(e){
console.log("getMachineNum fail:" + JSON.stringify(e));
}
},'../myhome/myhome','2')
}
注意
:页面POST请求header需配置为 {'content-type' : "application/x-www-form-urlencoded"},如:
initData:function () {
this.sendRequest({
url : "CompanyTeam/teamInfo",
data : {ct_id : ct_id},
method : "POST",
header: {'content-type' : "application/x-www-form-urlencoded"},
success:function (res) {
console.log("获取数据:" + JSON.stringify(res));
}
},"/pages/machineGroupOutput/machineGroupOutput","1")
},
故,可对网络请求封装继续优化。
1.3 网络请求封装优化
- main.js
Vue.prototype.sendRequest = function(param,backpage, backtype){
var _self = this,
url = param.url,
method = param.method,
header = {},
data = param.data || {},
token = "",
hideLoading = param.hideLoading || false;
//拼接完整请求地址
var requestUrl = this.siteBaseUrl + url;
//固定参数:仅仅在小程序绑定页面通过code获取token的接口默认传递了参数token = login
if(!data.token){//其他业务接口传递过来的参数中无token
token = uni.getStorageSync(this.sessionKey);//参数中无token时在本地缓存中获取
console.log("当前token:" + token);
if(!token){//本地无token需重新登录(退出时清缓存token)
_self.login(backpage, backtype);
return;
}else{
data.token = token;
}
}
var timestamp = Date.parse(new Date());//时间戳
data["timestamp"] = timestamp;
// #ifdef MP-WEIXIN
data["device"] = "wxapp";
data["ver"] = "1.1.30";
// #endif
// #ifdef APP-PLUS || H5
data["device"] = "iosapp";
data["ver"] = "1.0.0";
// #endif
//请求方式:GET或POST(POST需配置header: {'content-type' : "application/x-www-form-urlencoded"},)
if(method){
method = method.toUpperCase();//小写改为大写
if(method=="POST"){
header = {'content-type' : "application/x-www-form-urlencoded"};
}else{
header = {'content-type' : "application/json"};
}
}else{
method = "GET";
header = {'content-type' : "application/json"};
}
//用户交互:加载圈
if (!hideLoading) {
uni.showLoading({title:'加载中...'});
}
console.log("网络请求start");
//网络请求
uni.request({
url: requestUrl,
method: method,
header: header,
data: data,
success: res => {
console.log("网络请求success:" + JSON.stringify(res));
if (res.statusCode && res.statusCode != 200) {//api错误
uni.showModal({
content:"" + res.errMsg
});
return;
}
if (res.data.code) {//返回结果码code判断:0成功,1错误,-1未登录(未绑定/失效/被解绑)
if (res.data.code == "-1") {
_self.login(backpage, backtype);
return;
}
if (res.data.code != "0") {
uni.showModal({
showCancel:false,
content:"" + res.data.msg
});
return;
}
} else{
uni.showModal({
showCancel:false,
content:"No ResultCode:" + res.data.msg
});
return;
}
typeof param.success == "function" && param.success(res.data);
},
fail: (e) => {
console.log("网络请求fail:" + JSON.stringify(e));
uni.showModal({
content:"" + e.errMsg
});
typeof param.fail == "function" && param.fail(e.data);
},
complete: () => {
console.log("网络请求complete");
if (!hideLoading) {
uni.hideLoading();
}
typeof param.complete == "function" && param.complete();
return;
}
});
}
- 页面POST请求调用
initData:function () {
this.sendRequest({
url : "CompanyTeam/teamInfo",
method : "POST",
data : {ct_id : ct_id},
hideLoading : true,
success:function (res) {
console.log("获取数据:" + JSON.stringify(res));
}
},"/pages/machineGroupOutput/machineGroupOutput","1")
},
拓展:设置网络请求为同步可参考Promise 封装。大致可分为三种方案:请求嵌套(异步方式的成功回调里获取数据后再采用异步方式请求)、promise 或者await,具体实现可自行实践,这里不详细叙述。
2. 文件上传封装
(1) 未封装前index.vue页面使用
commitUnqualifiedInfoAndFile:function(filePath){
uni.uploadFile({
url: 'http://' + _self.getIP() + '/' + 'ticket/toCheck',
filePath: filePath,
name: 'image',
formData: {
token : uni.getStorageSync(this.sessionKey),
timestamp : Date.parse(new Date()),
style_id : "7",
production_id : "SCD778",
qualified_num:0
},
success: (res) => {
console.log("res:" + JSON.stringify(res));//json对象转json字符串
console.log("statusCode:" + res.statusCode);
console.log("uniapp上传文件api返回的data是字符串类型:"+ res.data);
var dataString = res.data;//json字符串
var res = JSON.parse(dataString);//json字符串转json对象
console.log("code:"+ res.code);
console.log("msg:"+ res.msg);
uni.showToast({
title:res.data.msg ? res.data.msg : "成功",
icon:'none'
});
console.log("data_1:"+ res.data.qualified_num);
console.log("data_2:"+ res.data.failed_num);
},
fail: (e) => {
console.log("网络请求fail");
},
complete: () => {
console.log("网络请求complete");
}
});
},
备注:后台返回的data值如下
{
"data": {
"msg": "质检完成",
"qualified_num": 41,
"failed_num": "17"
},
"code": "0",
"msg": "success"
}
打印结果:uniapp上传文件api返回的data是字符串类型,需先将data转换为json对象,之后再取里面的值
。
(2) main.js中封装网络请求
//上传文件
Vue.prototype.uploadFileRequest = function(param){
var _self = this,
url = param.url || "",
path = param.path || "",
name = param.name || "file",
data = param.data || {},
token = "";
if(url == ""){
url = _self.getUploadFileUrl();//默认的上传文件地址
}else{
url = "http://" + this.getIP() + "/" + url;
}
if(!data.token){
token = uni.getStorageSync(this.sessionKey);
console.log("当前token:" + token);
if(!token){
uni.redirectTo({url:'/pages/login1/login1'});
return;
}else{
data.token = token;
}
}
var timestamp = Date.parse(new Date());//时间戳
data["timestamp"] = timestamp;
console.log("网络请求start:url:" + url + ",params:" +JSON.stringify(data));
uni.uploadFile({
url: url,
filePath: path,
name: name,
formData: data,
success: (res) => {
console.log("网络请求success-res:" + JSON.stringify(res));//json对象转json字符串
console.log("网络请求success-statusCode:" + res.statusCode);
console.log("uniapp上传文件api返回的data是字符串类型:" + res.data);
if (res.statusCode && res.statusCode != 200) {//api错误(Error StatusCode)
uni.showToast({
/* title:res.errMsg */
title:"api错误",
icon:'none'
});
return;
}
var dataString = res.data;//json字符串
var res = JSON.parse(dataString);//json字符串转json对象
if (res.code) {
if (res.code != "0") {//Error ResultCode
uni.showToast({
title:res.msg,
icon:'none'
});
return;
}
} else {//No ResultCode
uni.showToast({
/* title:res.msg */
title:"无结果码",
icon:'none'
});
return;
}
typeof param.success == "function" && param.success(res);
},
fail: (e) => {
console.log("网络请求fail");
uni.showToast({
/* title: e.errMsg */
title:"请检查网络",
icon:'none'
});
typeof param.fail == "function" && param.fail(e.data);
},
complete: () => {
console.log("网络请求complete");
typeof param.complete == "function" && param.complete();
return;
}
});
}
(3) 封装后index.vue页面调用
commitUnqualifiedInfoAndFile:function(filePath){
_self.uploadFileRequest({
url:'ticket/toCheck',
path: filePath,
name: 'image',
data:{
style_id : "7",
production_id : "SCD778",
qualified_num:0,
},
success: (res) => {
console.log("res:" + JSON.stringify(res));//json对象转json字符串
uni.showToast({
title:res.data.msg ? res.data.msg : "成功",
icon:'none'
});
},
fail: (e) => {
},
complete: () => {
}
});
},
3. 所有网络请求封装为公用js文件
(1) http.js
const baseUrl = "http://api.liy.cn"
//网络判断
const hasNetwork = function(){
var result = true;
uni.getNetworkType({
success: function (res) {
console.log("网络类型:" + res.networkType);
if(res.networkType == "none"){
uni.showToast({
title:"网络未连接",
icon:'none'
});
result = false;
}
}
});
return result;
}
//登录请求
const sendLoginRequest = function(param){
//为什么程序未执行网络变化的监听:网络发生变化才会触发
// uni.onNetworkStatusChange(function(res){
// // console.log("网络类型:" + res.networkType + ",网络连接:" + res.isConnected);
// if(!res.isConnected){
// uni.showToast({
// title:"网络未连接",
// icon:'none'
// });
// return;
// }
// })
// if(!hasNetwork()){//移到页面中判断:适配按钮状态变化的逻辑
// return;
// }
var _self = this, data = param.data || {}, siteBaseUrl = baseUrl + "/";
uni.request({
url: siteBaseUrl + "user/login",
method: 'POST',
//header: {'content-type' : "application/json"},//默认
header: {'content-type' : "application/x-www-form-urlencoded"},
data: data,
success:function(res){
console.log("网络请求success:" + JSON.stringify(res));
if (res.statusCode && res.statusCode != 200) {//api错误(Error StatusCode)
uni.showToast({
/* title:res.errMsg */
title:"api错误",
icon:'none'
});
return;
}
if (res.data.code) {
if (res.data.code != "0") {//Error ResultCode
uni.showToast({
title:res.data.msg,
icon:'none'
});
return;
}
} else {//No ResultCode
uni.showToast({
/* title:res.data.msg */
title:"无结果码",
icon:'none'
});
return;
}
typeof param.success == "function" && param.success(res.data);
},
fail:function(e){
console.log("网络请求fail:" + JSON.stringify(e));
uni.showToast({
/* title:e.errMsg */
title:"请检查网络",
icon:'none'
});
typeof param.fail == "function" && param.fail(e.data);
},
complete:function(){
console.log("网络请求complete");
typeof param.complete == "function" && param.complete();
return;
}
});
}
//封装除登录外的业务网络请求
const sendRequest = function(param){
if(!hasNetwork()){//移到页面中判断:适配按钮状态变化的逻辑
return;
}
var _self = this,
url = param.url,
method = param.method,
header = {},
data = param.data || {},
token = "",
hideLoading = param.hideLoading || true;
//拼接完整请求地址
var requestUrl = baseUrl + "/" + url;
//固定参数:仅仅在小程序绑定页面通过code获取token的接口默认传递了参数token = login
if(!data.token){//其他业务接口传递过来的参数中无token
token = uni.getStorageSync(this.sessionKey);//参数中无token时在本地缓存中获取
console.log("当前token:" + token);
if(!token){//本地无token需重新登录(退出时清缓存token)
uni.redirectTo({url:'/pages/login/login'});
return;
}else{
data.token = token;
}
}
var timestamp = Date.parse(new Date());//时间戳
data["timestamp"] = timestamp;
var center_id = _self.getUserInfo().center_id || "";
data["center_id"] = center_id;
//请求方式:GET或POST(POST需配置header: {'content-type' : "application/x-www-form-urlencoded"},)
if(method){
method = method.toUpperCase();//小写改为大写
if(method=="POST"){
header = {'content-type' : "application/x-www-form-urlencoded"};
}else{
header = {'content-type' : "application/json"};
}
}else{
method = "GET";
header = {'content-type' : "application/json"};
}
//用户交互:加载圈
if (!hideLoading) {
uni.showLoading({title:'加载中...'});
}
console.log("网络请求start:url:" + requestUrl + ",params:" +JSON.stringify(data));
//网络请求
uni.request({
url: requestUrl,
method: method,
header: header,
data: data,
success: res => {
console.log("网络请求success:" + JSON.stringify(res));
if (res.statusCode && res.statusCode != 200) {//api错误
uni.showToast({
/* title: res.errMsg */
title:"api错误",
icon:'none'
});
return;
}
if (res.data.code) {//返回结果码code判断:0成功,1错误,-1未登录(未绑定/失效/被解绑)
if (res.data.code == "-1") {
uni.redirectTo({url:'/pages/login2/login2'});
return;
}
if (res.data.code != "0") {//code为1失败,code为0成功
uni.showToast({
title: res.data.msg,
icon:'none'
});
return;
}
} else{
uni.showToast({
/* title: res.data.msg */
title:"无结果码",
icon:'none'
});
return;
}
typeof param.success == "function" && param.success(res.data);
},
fail: (e) => {
console.log("网络请求fail:" + JSON.stringify(e));
uni.showToast({
/* title: e.errMsg */
title:"请检查网络",
icon:'none'
});
typeof param.fail == "function" && param.fail(e.data);
},
complete: () => {
console.log("网络请求complete");
if (!hideLoading) {
uni.hideLoading();
}
typeof param.complete == "function" && param.complete();
return;
}
});
}
//上传文件
const uploadFileRequest = function(param){
if(!hasNetwork()){//移到页面中判断:适配按钮状态变化的逻辑
return;
}
var _self = this,
url = param.url || "",
path = param.path || "",
name = param.name || "file",
data = param.data || {},
token = "";
if(url == ""){
url = _self.getUploadFileUrl();//默认的上传文件地址
}else{
url = baseUrl + "/" + url;
}
if(!data.token){
token = uni.getStorageSync(this.sessionKey);
console.log("当前token:" + token);
if(!token){
uni.redirectTo({url:'/pages/login2/login2'});
return;
}else{
data.token = token;
}
}
var timestamp = Date.parse(new Date());//时间戳
data["timestamp"] = timestamp;
console.log("网络请求start:url:" + url + ",params:" +JSON.stringify(data));
uni.uploadFile({
url: url,
filePath: path,
name: name,
formData: data,
success: (res) => {
console.log("网络请求success-res:" + JSON.stringify(res));//json对象转json字符串
console.log("网络请求success-statusCode:" + res.statusCode);
console.log("uniapp上传文件api返回的data是字符串类型:" + res.data);
if (res.statusCode && res.statusCode != 200) {//api错误(Error StatusCode)
uni.showToast({
/* title:res.errMsg */
title:"api错误",
icon:'none'
});
return;
}
var dataString = res.data;//json字符串
var res = JSON.parse(dataString);//json字符串转json对象
if (res.code) {
if (res.code != "0") {//Error ResultCode
uni.showToast({
title:res.msg,
icon:'none'
});
return;
}
} else {//No ResultCode
uni.showToast({
/* title:res.msg */
title:"无结果码",
icon:'none'
});
return;
}
typeof param.success == "function" && param.success(res);
},
fail: (e) => {
console.log("网络请求fail");
uni.showToast({
/* title: e.errMsg */
title:"请检查网络",
icon:'none'
});
typeof param.fail == "function" && param.fail(e.data);
},
complete: () => {
console.log("网络请求complete");
typeof param.complete == "function" && param.complete();
return;
}
});
}
export default {
sendLoginRequest,
sendRequest,
uploadFileRequest
}
(2) 单页面引入js文件并调用
<script>
import Http from '../../common/http.js'
var _self;
export default {
data() {
return {
logining: false
}
},
methods: {
login:function(){
_self = this;
if(!this.Http.hasNetwork()){
return;
}
_self.logining = true;//按钮不可用
Http.sendLoginRequest({
data: {
mobile : "15639150623",
password : "aaaaaa"
},
success:function(res){
uni.switchTab({
url:'../tabBar/home/home'
})
},
fail:function(e){},
complete:function(){
_self.logining = false;//按钮可用
}
})
}
}
}
</script>
(3) 全局引入js文件并调用
- main.js
import Vue from 'vue'
import App from './App'
import Http from './common/http.js'
Vue.config.productionTip = false
Vue.prototype.Http = Http
App.mpType = 'app'
const app = new Vue({
Http,
...App
})
app.$mount()
- 页面调用
<script>
// import Http from '../../common/http.js'
var _self;
export default {
data() {
return {
logining: false
}
},
methods: {
login:function(){
_self = this;
if(!this.Http.hasNetwork()){
return;
}
_self.logining = true;//按钮不可用
this.Http.sendLoginRequest({
data: {
mobile : "15639150623",
password : "aaaaaa"
},
success:function(res){
uni.switchTab({
url:'../tabBar/home/home'
})
},
fail:function(e){},
complete:function(){
_self.logining = false;//按钮可用
}
})
}
}
}
</script>
说明:目前已发布到uniapp插件市场,有需要请移步网络请求封装。