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 });
第五步:再次封装,习惯使用
- 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' // 生产环境
- ;