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。

二,网络请求封装

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

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

 第二步:拦截器定义

   interceptor: {
     request: null,
     response: null
   },

 第三步:处理传入的参数

     options.baseUrl = options.baseUrl || this.config.baseUrl
     options.dataType = options.dataType || this.config.dataType
     options.url = options.baseUrl + options.url
     options.data = options.data || {}
     options.method = options.method.toUpperCase() || this.config.method

     // 请求头部类型提供自定义
     const contentType = options.contentType;
     delete options.contentType;//      // 'Content-Type': 'application/x-www-form-urlencoded'
     const headers = contentType ? { 'Content-Type': contentType } : this.config.baseUrl; //默认 application/json;charset=UTF-8 json数据传参
     options.header = Object.assign({}, options.header, headers);

 第四步:发送网络请求

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

 return new Promise((resolve, reject) => {
       let _config: any = null

       options.complete = (response: any) => {
         let statusCode = response.statusCode
         response.config = _config
         if (process.env.NODE_ENV === 'development') {
           if (statusCode === 200) {
             console.log("【" + _config.requestId + "】 结果:" + JSON.stringify(response.data))
           }
         }
         if (this.interceptor.response) {
           // @ts-ignore
           let newResponse = this.interceptor.response(response)
           if (newResponse) {
             response = newResponse
           }
         }
         // 统一的响应日志记录
         _reslog(response)
         if (statusCode === 200) { //成功
           const result = _getResult(response.data);//网络请求成功后数据处理
           resolve(result);
         } else {
           reject(response)
         }
       }

       _config = Object.assign({}, this.config, options)
       _config.requestId = new Date().getTime()

       if (this.interceptor.request) {
         // @ts-ignore
         this.interceptor.request(_config)
       }

       // 统一的请求日志记录
       _reqlog(_config)
       uni.request(_config);
     });

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

 /**
  * 服务统一处理 添加拦截器 并抛出使用
  */
 function requestApi(url: String, options: any) {
   if (!options) {
     options = {}
   }
   /**
   * @description: 响应拦截器
   * @param {object} 当前请求成功回调数据
   * @return 不return对象,则不返回数据
   */
   // @ts-ignore
   httpService.interceptor.response = (response: any) => {
     console.log('个性化response....', JSON.stringify(response))
     //判断返回状态 执行相应操作
     return response;
   }
   /**
   * @description: 请求拦截器
   * @param {object} 当前请求配置参数
   * @return 不return对象,则不发送当前请求
   */
   // @ts-ignore
   httpService.interceptor.request = (config: any) => {
     console.log('config....', JSON.stringify(config))
     //获取配置信息 统一添加配置与判断
     return config;
   }
   options.url = url
   return httpService.request(options);
 }

 第六步:完整代码

 import { configBaseUrl, GET } from "./const";

 const httpService = {
   config: {
     baseUrl: configBaseUrl,
     header: {
       'Content-Type': 'application/json;charset=UTF-8',
     },
     data: {},
     method: GET,
     dataType: "json",  /* 如设为json,会对返回的数据做一次 JSON.parse */
     responseType: "text",
     success() { },
     fail() { },
     complete() { }
   },
   interceptor: {
     request: null,
     response: null
   },
   request(options: any) {
     if (!options) {
       options = {}
     }
     options.baseUrl = options.baseUrl || this.config.baseUrl
     options.dataType = options.dataType || this.config.dataType
     options.url = options.baseUrl + options.url
     options.data = options.data || {}
     options.method = options.method.toUpperCase() || this.config.method

     // 请求头部类型提供自定义
     const contentType = options.contentType;
     delete options.contentType;//      // 'Content-Type': 'application/x-www-form-urlencoded'
     const headers = contentType ? { 'Content-Type': contentType } : this.config.baseUrl; //默认 application/json;charset=UTF-8 json数据传参
     options.header = Object.assign({}, options.header, headers);
     // 加密数据

     // 数据签名
         /*
         _token = {'token': getStorage(STOREKEY_LOGIN).token || 'undefined'},
         _sign = {'sign': sign(JSON.stringify(options.data))}
         options.header = Object.assign({}, options.header, _token,_sign)
         */

     return new Promise((resolve, reject) => {
       let _config: any = null

       options.complete = (response: any) => {
         let statusCode = response.statusCode
         response.config = _config
         if (process.env.NODE_ENV === 'development') {
           if (statusCode === 200) {
             console.log("【" + _config.requestId + "】 结果:" + JSON.stringify(response.data))
           }
         }
         if (this.interceptor.response) {
           // @ts-ignore
           let newResponse = this.interceptor.response(response)
           if (newResponse) {
             response = newResponse
           }
         }
         // 统一的响应日志记录
         _reslog(response)
         if (statusCode === 200) { //成功
           const result = _getResult(response.data);//网络请求成功后数据处理
           resolve(result);
         } else {
           reject(response)
         }
       }

       _config = Object.assign({}, this.config, options)
       _config.requestId = new Date().getTime()

       if (this.interceptor.request) {
         // @ts-ignore
         this.interceptor.request(_config)
       }

       // 统一的请求日志记录
       _reqlog(_config)
       uni.request(_config);
     });
   },
 }

 /**
  * 服务统一处理 添加拦截器 并抛出使用
  */
 function requestApi(url: String, options: any) {
   if (!options) {
     options = {}
   }
   /**
   * @description: 响应拦截器
   * @param {object} 当前请求成功回调数据
   * @return 不return对象,则不返回数据
   */
   // @ts-ignore
   httpService.interceptor.response = (response: any) => {
     console.log('个性化response....', JSON.stringify(response))
     //判断返回状态 执行相应操作
     return response;
   }
   /**
   * @description: 请求拦截器
   * @param {object} 当前请求配置参数
   * @return 不return对象,则不发送当前请求
   */
   // @ts-ignore
   httpService.interceptor.request = (config: any) => {
     console.log('config....', JSON.stringify(config))
     //获取配置信息 统一添加配置
     return config;
   }
   options.url = url
   return httpService.request(options);
 }

 /**
  * 请求接口日志记录
  */
 function _reqlog(req: any) {
   if (process.env.NODE_ENV === 'development') {
     console.log("【" + req.requestId + "】 地址:" + req.url)
     if (req.data) {
       console.log("【" + req.requestId + "】 请求参数:" + JSON.stringify(req.data))
     }
   }
   // 调接口异步写入日志数据库
 }

 /**
  * 响应接口日志记录
  */
 function _reslog(res: any) {
   let _statusCode = res.statusCode;
   if (process.env.NODE_ENV === 'development') {
     console.log("【" + res.config.requestId + "】 地址:" + res.config.url)
     if (res.config.data) {
       console.log("【" + res.config.requestId + "】 请求参数:" + JSON.stringify(res.config.data))
     }
     console.log("【" + res.config.requestId + "】 响应结果:" + JSON.stringify(res))
   }

   // 除了接口服务错误外,其他日志调接口异步写入日志数据库
   switch (_statusCode) {
     case 200:
       break;
     case 401:
       break;
     case 404:
       ToastWarn('找不了资源文件!')
       break;
     default:
       ToastWarn('服务器异常!')
       break;
   }
 }

 /**
  * 结果统一处理
  */
 function _getResult(res: any) {
   if (res.httpCode === 200) {
     return { result: res.data };
   }
 }

 export default requestApi;

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

3.1,store中调用

第一步:引入接口

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

第二步:在store中使用

  login({ commit }, userInfo) {//store actions中的方法
     const { username, password } = userInfo
     return new Promise((resolve, reject) => {
       login({ username: username.trim(), password: password }).then(response => {//登录接口
         const { result } = response
         console.log('result===', result)
         resolve(result)
       }).catch(error => {
         reject(error)
       })
     })
   }

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

  this.$store.dispatch('user/login', { username: this.username, password: this.password })
                 .then(() => {
                     ToastSuccess('登陆成功');
                     uni.switchTab({
                         url: '../index/index',
                     })
                 }).catch(() => {
                     ToastWarn('登陆失败');
                 });

3.2,封装统一的api入口

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

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

 // https://webpack.js.org/guides/dependency-management/#requirecontext
 const apisFiles = require.context('./api', false, /\.ts$/);

 // you do not need `import user from './api/user'`
 // it will auto require all api from api file
 const apis = apisFiles.keys().reduce((apis, apiPath) => {
     // set './user.ts' => 'user'
     // const moduleName = apiPath.replace(/^\.\/(.*)\.\w+$/, '$1');//文件名
     const value = apisFiles(apiPath);
     apis = Object.assign({}, apis, value);//将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
     return apis;
 }, {});

 export default {
     ...apis,
 }

第二步:使用接口服务

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

 import requestApi from '@/utils/request';
 import { POST } from '@/utils/const';

 /*
 ***登录***
 */
 export function login(data: any) {
     return requestApi('/api/v1/yingqi/user/login', {
         method: POST,
         data: {
             loginCode: data.username,
             password: data.password
         },
     });
 }

第三步:统一接口入口

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

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

第四步:页面中使用

  this.$servicesApi.getSingleDataById().then((response: any) => {
             const { result } = response
             console.log('result===', result)
         }).catch((error: any) => {
             console.log('error===', error)
         })

其他参数配置文件

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之缓存类封装

uni-app之网络请求的更多相关文章

  1. IOS 京东相关app 出现“网络请求失败,请检查您的网络设置”的解决办法

    问题情况 在IOS系统下,下载安装或者更新新版的京东相关app之后,打开app直接就是“网络请求失败,请检查网络设置”,无论是数据连接还是wifi都试了,都是网络请求失败. 然而打开无线局域网-使用无 ...

  2. 分析移动端APP的网络请求抓包

    为了方便,本文以 iOS 系统来进行演示. 使用代理 移动操作系统中都有可以设定系统代理的设置,比如在 iOS 中可以通过 Settings->WLAN 看到很多 Networks,通过点击它们 ...

  3. nginx android app 慢网络请求超时

    最近遇到了android 在慢网络下面请求服务器报 java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by ...

  4. 使用Fiddler重定向App的网络请求

    前言 开发中手机app只能访问生产环境地址,所以给开发调试带来不便,可以通过Fiddler的代理和urlreplace方式解决. 步骤 1.开启Fiddler的代理模式Tools->Teleri ...

  5. Swift - 网络请求报App Transport Security has blocked a cleartext错

    使用Xcode7编写iOS9应用时,如果获取http://数据时会报如下错误: App Transport Security has blocked a cleartext HTTP (http:// ...

  6. 2020,最新APP重构:网络请求框架

    在现在的app,网络请求是一个很重要的部分,app中很多部分都有或多或少的网络请求,所以在一个项目重构时,我会选择网络请求框架作为我重构的起点.在这篇文章中我所提出的架构,并不是所谓的 最好 的网络请 ...

  7. 使用charles proxy for Mac来抓取手机App的网络包

    之前做Web项目的时候,经常会使用Fiddler(Windows下).Charles Proxy(Mac下)来抓包,调试一些东西:现在搞Android App开发,有时候也需要分析手机App的网络请求 ...

  8. 使用Charles对Android App的https请求进行抓包

    本文背景 公司新项目要求抓取目前市面上一些热门App的数据,经过研究发现很多App的网络请求都使用https进行数据传输,这样问题就来了,http使用明文传输所有请求都能拦截到,而https请求无法拦 ...

  9. uni-app 网络请求

    uni.request发起网络请求 url 开发者服务器接口地址 data 请求的参数 header method dataType responseType 设置响应的数据类型 statusCode ...

  10. 网络请求报错:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

    iOS9引入了新特性App Transport Security (ATS).详情:App Transport Security (ATS) 如果你想设置不阻止任何网络,只需要在info.plist文 ...

随机推荐

  1. Numpy 排序和使用索引

    # 导包 import numpy as np 排序 .sort() x = np.arange(16) # array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...

  2. 【Spdy协议简介】

    一.SPDY协议诞生记 SPDY (SPDY 是 Speedy 的昵音,意思是更快)是 Google 开发的基于传输控制协议 (TCP) 的应用层协议 ,那么为什么要搞一个SPDY出来呢?距离万维网之 ...

  3. 最新开源跳板机(堡垒机)系统 Jumpserver介绍

    Jumpserver 是全球首款完全开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 的专业运维审计系统. Jumpserver 使用 Python / Django 进行开发,遵 ...

  4. GPIO硬件资源的申请,内核空间和用户空间的数据交换,ioctl(.....),设备文件的自动创建

    1.通过GPIO库函数控制LED   open("/dev/myleds",...)       close(fd)   ----------------------------- ...

  5. 字符串(str)

    把字符连成串串. 在python中⽤用', ", ''', """引起来的内容被称为字符串串. 字符串是不可变的对象,所以任何操作对原字符串是不会有任何影响的 ...

  6. .NET Core前后端分离快速开发框架(Core.3.0+AntdVue)

    .NET Core前后端分离快速开发框架(Core.3.0+AntdVue) 目录 引言 简介 环境搭建 开发环境要求 基础数据库构建 数据库设计规范 运行 使用教程 全局配置 快速开发 管理员登录 ...

  7. (Codeforce)Correct Solution?

    One cold winter evening Alice and her older brother Bob was sitting at home near the fireplace and g ...

  8. 回声消除中的LMS和NLMS算法与MATLAB实现

    自适应滤波是数字信号处理的核心技术之一,在科学和工业上有着广泛的应用领域.自适应滤波技术应用广泛,包括回波抵消.自适应均衡.自适应噪声抵消和自适应波束形成.回声对消是当今通信系统中普遍存在的现象.声回 ...

  9. Python 常用模块系列(2)--time module and datatime module

    import time print (help(time)) #time帮助文档 1. time模块--三种时间表现形式: 1° 时间戳--如:time.time()  #从python创立以来,到当 ...

  10. Redis的内存淘汰策略

    Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...