uni-app之网络请求

uni-app之网络请求

一,介绍

    uni.request(OBJECT),发起网络请求,以下主要是一些特殊的参数说明,详细的可查看uni-app官网

1,method的有效值必须是大写,默认GET方式;

2,success 返回参数说明

参数 类型 说明
data Object/String/ArrayBuffer 开发者服务器返回的数据
statusCode Number 开发者服务器返回的 HTTP 状态码
header Object 开发者服务器返回的 HTTP Response Header


3,传参数据说明

最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:

    • 对于 GET 方法,会将数据转换为 query string。例如 { name: 'name', age: 18 } 转换后的结果是 name=name&age=18
    • 对于 POST 方法且 header['content-type'] 为 application/json 的数据,会进行 JSON 序列化。
    • 对于 POST 方法且 header['content-type'] 为 application/x-www-form-urlencoded 的数据,会将数据转换为 query string。

二,网络请求封装

 第一步:参数统一初始化配置

1 import { configBaseUrl, GET } from "./const"
 1   config: {
 2     baseUrl: configBaseUrl,
 3     header: {
 4       'Content-Type': 'application/json;charset=UTF-8',
 5     },
 6     data: {},
 7     method: GET,
 8     dataType: "json",  /* 如设为json,会对返回的数据做一次 JSON.parse */
 9     responseType: "text",
10     success() { },
11     fail() { },
12     complete() { }
13   },

 第二步:拦截器定义

1   interceptor: {
2     request: null,
3     response: null
4   },

 第三步:处理传入的参数

 1     options.baseUrl = options.baseUrl || this.config.baseUrl
 2     options.dataType = options.dataType || this.config.dataType
 3     options.url = options.baseUrl + options.url
 4     options.data = options.data || {}
 5     options.method = options.method.toUpperCase() || this.config.method
 6 
 7     // 请求头部类型提供自定义
 8     const contentType = options.contentType;
 9     delete options.contentType;//      // 'Content-Type': 'application/x-www-form-urlencoded'
10     const headers = contentType ? { 'Content-Type': contentType } : this.config.baseUrl; //默认 application/json;charset=UTF-8 json数据传参
11     options.header = Object.assign({}, options.header, headers);

 第四步:发送网络请求

使用Promise方法,方便调用获取返回的参数;并做统一的处理以及日志记录。

 1 return new Promise((resolve, reject) => {
 2       let _config: any = null
 3 
 4       options.complete = (response: any) => {
 5         let statusCode = response.statusCode
 6         response.config = _config
 7         if (process.env.NODE_ENV === 'development') {
 8           if (statusCode === 200) {
 9             console.log("【" + _config.requestId + "】 结果:" + JSON.stringify(response.data))
10           }
11         }
12         if (this.interceptor.response) {
13           // @ts-ignore
14           let newResponse = this.interceptor.response(response)
15           if (newResponse) {
16             response = newResponse
17           }
18         }
19         // 统一的响应日志记录
20         _reslog(response)
21         if (statusCode === 200) { //成功
22           const result = _getResult(response.data);//网络请求成功后数据处理
23           resolve(result);
24         } else {
25           reject(response)
26         }
27       }
28 
29       _config = Object.assign({}, this.config, options)
30       _config.requestId = new Date().getTime()
31 
32       if (this.interceptor.request) {
33         // @ts-ignore
34         this.interceptor.request(_config)
35       }
36 
37       // 统一的请求日志记录
38       _reqlog(_config)
39       uni.request(_config);
40     });

 第五步:再次封装,习惯使用

扫描二维码关注公众号,回复: 8125720 查看本文章
 1 /**
 2  * 服务统一处理 添加拦截器 并抛出使用
 3  */
 4 function requestApi(url: String, options: any) {
 5   if (!options) {
 6     options = {}
 7   }
 8   /**
 9   * @description: 响应拦截器
10   * @param {object} 当前请求成功回调数据
11   * @return 不return对象,则不返回数据
12   */
13   // @ts-ignore
14   httpService.interceptor.response = (response: any) => {
15     console.log('个性化response....', JSON.stringify(response))
16     //判断返回状态 执行相应操作
17     return response;
18   }
19   /**
20   * @description: 请求拦截器
21   * @param {object} 当前请求配置参数
22   * @return 不return对象,则不发送当前请求
23   */
24   // @ts-ignore
25   httpService.interceptor.request = (config: any) => {
26     console.log('config....', JSON.stringify(config))
27     //获取配置信息 统一添加配置与判断
28     return config;
29   }
30   options.url = url
31   return httpService.request(options);
32 }

 第六步:完整代码

  1 import { configBaseUrl, GET } from "./const";
  2 
  3 const httpService = {
  4   config: {
  5     baseUrl: configBaseUrl,
  6     header: {
  7       'Content-Type': 'application/json;charset=UTF-8',
  8     },
  9     data: {},
 10     method: GET,
 11     dataType: "json",  /* 如设为json,会对返回的数据做一次 JSON.parse */
 12     responseType: "text",
 13     success() { },
 14     fail() { },
 15     complete() { }
 16   },
 17   interceptor: {
 18     request: null,
 19     response: null
 20   },
 21   request(options: any) {
 22     if (!options) {
 23       options = {}
 24     }
 25     options.baseUrl = options.baseUrl || this.config.baseUrl
 26     options.dataType = options.dataType || this.config.dataType
 27     options.url = options.baseUrl + options.url
 28     options.data = options.data || {}
 29     options.method = options.method.toUpperCase() || this.config.method
 30 
 31     // 请求头部类型提供自定义
 32     const contentType = options.contentType;
 33     delete options.contentType;//      // 'Content-Type': 'application/x-www-form-urlencoded'
 34     const headers = contentType ? { 'Content-Type': contentType } : this.config.baseUrl; //默认 application/json;charset=UTF-8 json数据传参
 35     options.header = Object.assign({}, options.header, headers);
 36     // 加密数据
 37 
 38     // 数据签名
 39         /* 
 40         _token = {'token': getStorage(STOREKEY_LOGIN).token || 'undefined'},
 41         _sign = {'sign': sign(JSON.stringify(options.data))}
 42         options.header = Object.assign({}, options.header, _token,_sign) 
 43         */
 44 
 45     return new Promise((resolve, reject) => {
 46       let _config: any = null
 47 
 48       options.complete = (response: any) => {
 49         let statusCode = response.statusCode
 50         response.config = _config
 51         if (process.env.NODE_ENV === 'development') {
 52           if (statusCode === 200) {
 53             console.log("【" + _config.requestId + "】 结果:" + JSON.stringify(response.data))
 54           }
 55         }
 56         if (this.interceptor.response) {
 57           // @ts-ignore
 58           let newResponse = this.interceptor.response(response)
 59           if (newResponse) {
 60             response = newResponse
 61           }
 62         }
 63         // 统一的响应日志记录
 64         _reslog(response)
 65         if (statusCode === 200) { //成功
 66           const result = _getResult(response.data);//网络请求成功后数据处理
 67           resolve(result);
 68         } else {
 69           reject(response)
 70         }
 71       }
 72 
 73       _config = Object.assign({}, this.config, options)
 74       _config.requestId = new Date().getTime()
 75 
 76       if (this.interceptor.request) {
 77         // @ts-ignore
 78         this.interceptor.request(_config)
 79       }
 80 
 81       // 统一的请求日志记录
 82       _reqlog(_config)
 83       uni.request(_config);
 84     });
 85   },
 86 }
 87 
 88 /**
 89  * 服务统一处理 添加拦截器 并抛出使用
 90  */
 91 function requestApi(url: String, options: any) {
 92   if (!options) {
 93     options = {}
 94   }
 95   /**
 96   * @description: 响应拦截器
 97   * @param {object} 当前请求成功回调数据
 98   * @return 不return对象,则不返回数据
 99   */
100   // @ts-ignore
101   httpService.interceptor.response = (response: any) => {
102     console.log('个性化response....', JSON.stringify(response))
103     //判断返回状态 执行相应操作
104     return response;
105   }
106   /**
107   * @description: 请求拦截器
108   * @param {object} 当前请求配置参数
109   * @return 不return对象,则不发送当前请求
110   */
111   // @ts-ignore
112   httpService.interceptor.request = (config: any) => {
113     console.log('config....', JSON.stringify(config))
114     //获取配置信息 统一添加配置
115     return config;
116   }
117   options.url = url
118   return httpService.request(options);
119 }
120 
121 /**
122  * 请求接口日志记录
123  */
124 function _reqlog(req: any) {
125   if (process.env.NODE_ENV === 'development') {
126     console.log("【" + req.requestId + "】 地址:" + req.url)
127     if (req.data) {
128       console.log("【" + req.requestId + "】 请求参数:" + JSON.stringify(req.data))
129     }
130   }
131   // 调接口异步写入日志数据库
132 }
133 
134 /**
135  * 响应接口日志记录
136  */
137 function _reslog(res: any) {
138   let _statusCode = res.statusCode;
139   if (process.env.NODE_ENV === 'development') {
140     console.log("【" + res.config.requestId + "】 地址:" + res.config.url)
141     if (res.config.data) {
142       console.log("【" + res.config.requestId + "】 请求参数:" + JSON.stringify(res.config.data))
143     }
144     console.log("【" + res.config.requestId + "】 响应结果:" + JSON.stringify(res))
145   }
146 
147   // 除了接口服务错误外,其他日志调接口异步写入日志数据库
148   switch (_statusCode) {
149     case 200:
150       break;
151     case 401:
152       break;
153     case 404:
154       ToastWarn('找不了资源文件!')
155       break;
156     default:
157       ToastWarn('服务器异常!')
158       break;
159   }
160 }
161 
162 /**
163  * 结果统一处理
164  */
165 function _getResult(res: any) {
166   if (res.httpCode === 200) {
167     return { result: res.data };
168   }
169 }
170 
171 export default requestApi;

三,使用封装方法(vue项目皆可按如下封装调用)

3.1,store中调用

第一步:引入接口

1 import { login } from '../../services/api/user'

第二步:在store中使用

 1  login({ commit }, userInfo) {//store actions中的方法
 2     const { username, password } = userInfo
 3     return new Promise((resolve, reject) => {
 4       login({ username: username.trim(), password: password }).then(response => {//登录接口
 5         const { result } = response
 6         console.log('result===', result)
 7         resolve(result)
 8       }).catch(error => {
 9         reject(error)
10       })
11     })
12   }

第三步:在页面中调用actions方法

1  this.$store.dispatch('user/login', { username: this.username, password: this.password })
2                 .then(() => {
3                     ToastSuccess('登陆成功');
4                     uni.switchTab({
5                         url: '../index/index',
6                     })
7                 }).catch(() => {
8                     ToastWarn('登陆失败');
9                 });

3.2,封装统一的api入口

第一步:封装接口服务统一入口

在services中添加文件index.ts,添加如下代码

 1 // https://webpack.js.org/guides/dependency-management/#requirecontext
 2 const apisFiles = require.context('./api', false, /\.ts$/);
 3 
 4 // you do not need `import user from './api/user'`
 5 // it will auto require all api from api file
 6 const apis = apisFiles.keys().reduce((apis, apiPath) => {
 7     // set './user.ts' => 'user'
 8     // const moduleName = apiPath.replace(/^\.\/(.*)\.\w+$/, '$1');//文件名
 9     const value = apisFiles(apiPath);
10     apis = Object.assign({}, apis, value);//将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
11     return apis;
12 }, {});
13 
14 export default {
15     ...apis,
16 }

第二步:使用接口服务

添加api文件夹,并添加ts文件,名字可随意命名

 1 import requestApi from '@/utils/request';
 2 import { POST } from '@/utils/const';
 3 
 4 /*
 5 ***登录***
 6 */
 7 export function login(data: any) {
 8     return requestApi('/api/v1/yingqi/user/login', {
 9         method: POST,
10         data: {
11             loginCode: data.username,
12             password: data.password
13         },
14     });
15 }

第三步:统一接口入口

在main.js添加如下代码即可

1 import servicesApi from '@/services';
2 Vue.prototype.$servicesApi = servicesApi

第四步:页面中使用

1  this.$servicesApi.getSingleDataById().then((response: any) => {
2             const { result } = response
3             console.log('result===', result)
4         }).catch((error: any) => {
5             console.log('error===', error)
6         })

其他参数配置文件

export const GET: String = 'GET';
export const POST: String = 'POST';
export const PUT: String = 'PUT';
export const PATCH: String = 'PATCH';
export const DELETE: String = 'DELETE';
export const UPDATE: String = 'UPDATE';
//************************************************【 请求基础路径 】*************************************************
export const configBaseUrl: String = process.env.NODE_ENV === 'development' ?
    'http://127.0.0.1:8880'  // 开发环境
    : 'http://x.x.x.x:8880' // 生产环境
    ;

下一章->uni-app,vue,react,Trao之缓存类封装

猜你喜欢

转载自www.cnblogs.com/jackson-yqj/p/11805495.html