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. 说一说JVM双亲委派机制与Tomcat

    双亲委派模型与JVM 类加载 讲个故事: 以前,爱捣鼓的小明突然灵机一动,写出了下面的代码 package java.lang; public class String { //...复制真正Stri ...

  2. nginx跨域解决方案

    nginx跨域解决方案Access to Font at 'http://47.104.86.187/yinjiatoupiao2/iconfont/iconfont.woff' from origi ...

  3. mysql并发量过大造成 update语句更新错误

    mysql并发量过大造成 update语句更新错误 在同一字段的时候更新的时候 如果并发量太大 就会更新错误 这个时候只能用 swoole 消息队列更新

  4. linux 安装swoole扩展方法

    linux 安装swoole扩展方法 wget https://github.com/swoole/swoole-src/archive/v1.9.23.tar.gz接下去就不说了 说明下 下载swo ...

  5. Hibernate的多对多关系

    1.表的关系: 分别有三个表:课程表.学生表.分数表.课程和学生的关系是多对多的,因为一个学生对应多个课程,而一个课程被多个学生选修.如果用一对多.多对一的观点来看待课程和学生的关系显然是不对的,因为 ...

  6. go中的数据结构接口-interface

    1. 接口的基本使用 golang中的interface本身也是一种类型,它代表的是一个方法的集合.任何类型只要实现了接口中声明的所有方法,那么该类就实现了该接口.与其他语言不同,golang并不需要 ...

  7. 为什么Python类语法应该不同?

    做过python的人你会发现想要的东西跟它原有的是不同的.Python对我来说是真的是这样.如果可以的话,对于Python中很多的我想要改的东西,我有很多的想法.现在我向您讲述其中一个:类定义的语法. ...

  8. Prometheus+Altermanager钉钉报警

    Prometheus+Altermanager钉钉报警 一.添加钉钉机器人 参考钉钉官方文档:https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq ...

  9. AsyncDisplayKit编译和使用注意事项

    Facebook开源框架,在github上可下载到.首先要编译AsyncDisplayKit库项目,有可能会出现下面错误: cocoaPods是基于ruby的项目版本控制软件,如果是ruby新手就会不 ...

  10. 机器学习 TensorFlow 实现智能鉴黄

    前言 最近在做一款图床服务,关注公号的小伙伴一定记得小柒曾说过,会在周末放出的,不好意思放大家鸽子了.之所以一直没敢放出,是因为鉴黄接口一直没调试好,虽然我对公号的小伙伴百分之百信任,奈何互联网鱼龙混 ...