微信小程序 wx.request封装

  • Post author:
  • Post category:小程序


参考链接:

(1)

详解微信小程序网络请求接口封装


https://blog.csdn.net/zyplll/article/details/112272324

(2)

微信小程序 wx.request 的封装


https://www.wxapp-union.com/portal.php?mod=view&aid=3660

(3)

微信小程序wx.request的简单封装,超详细


https://blog.csdn.net/qq_43677737/article/details/107769366

(4)

微信小程序接口数据封装 (附前端面试题)


https://blog.csdn.net/weixin_45616142/article/details/107888591

(5)

微信小程序 数据封装,参数传值等经验分享


https://www.jb51.net/article/102471.htm

为实现定制要求和方便调用,对微信小程序的网络请求接口进行了封装

在根目录新建api文件夹并新建httpRequest.js与config.js文件


wx.request(Object)原型

wx.request({
      url: 'http://localhost:4000/top/playlist/highquality',//请求的接口地址
      method:"get|post|其他",//http请求数据的方式,默认是get
      data:{name:'',id:''},//请求的参数,如name和id
      header:{//请求头设置,根据需要自己设置
        //content-type默认为application/json
        'content-type':"application/x-www-form-urlencoded"
      },
      success(res){//请求成功时的回调函数
        console.log(res);
      },
      fail(msg){
          console.log(msg);//请求失败的回调函数
      }
    })

可能会遇到一个错误。所以,需要在微信开发者工具中设置“不校验合法域名”。

在这里插入图片描述


封装API接口的原因


因为本身就是一出现是一大段,自然如果不封包起来通过调用的方式进行整理的话,直接放到网站源码中,自然就会加大的源码的体积,而且还会影响到代码的美现。而且现在很多的杀来毒软件都把JS代码误报为病毒,况源且JS代码外露也很容易让不良分子找到攻击网站的参照物。


API接口封装的好处

  1. 提高网站的打开速度。
  2. 符合SEO搜索引擎思路。
  3. 以便于我们后期的维护,如果当我们的接口发生更改的时候,我们修改也很方便,不需要再一个页面的查找。
  4. 所以,对于提高网站访问zhidao速度,最好把JS代码封包起来,而且还要通过ROBOT文件把之屏蔽掉,毕竟这些都是搜索引挚不能识别的,外放对于提高收录只有坏外没有好处。
  5. 所以,为了收录、为了访问速度能封装的JS代码就尽量封装。



一、例子1

  1. 设置请求域名
// 设置请求域名
let ENV = __wxConfig.envVersion
let httpUrl = '',
if (ENV == 'develop') {
  // 测试版开发环境域名
  httpUrl = 'https://*******.com/api';
} else if (ENV == 'trial') {
  // // 体验版环境域名
  httpUrl = 'http://*******.com/api';
} else if (ENV == 'release') {
  // 线上环境域名
  httpUrl = 'https://*******.com/api';
}
export default httpUrl
  1. 在utils下方建立一个qs文件

    根据自己项目数据需求是否下载qs(网址:

    https://gitee.com/zyplll/qs-file

  2. 封装httpRequest

import Qs from '../utils/qs'
import httpUrl from './config'
const apiRequest = (option) => {
  /*
  option.url:请求地址
  option.header:头信息
  option.params:参数
  */
  let promise = new Promise(function (resolve, reject) {
    wx.showLoading({
      title: '努力加载中',
      mask: true
    });
    // 设置请求头
    let headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-Requested-With': 'XMLHttpRequest'
    }
    // 对数据进行处理转换
    let params = Qs.stringify(option.params, {
      arrayFormat: 'indices',
      allowDots: true
    }).replace(/\[\d+\]=/g, "=")
    wx.request({

      url: httpUrl.connectorUrl + option.url,
      data: params,
      method: 'post',
      header: headers,
      // 超时时间
      timeout: 60000,
      success: function (res) {
        wx.hideLoading()
        if (res.statusCode == 200) {
          res = res.data
          if (res.code == -1) {
            // 跳转到登录

          } else if (res.code == 2) {
            wx.showModal({
              title: '提示',
              content: '您没有访问权限',
              success: function () {
                // 返回上一页
                wx.navigateBack()
                if (res.confirm) {
                  // 点击了确定
                } else if (res.cancel) {
                  // 点击了取消
                }
              }
            })
          } else  {
            // 请求成功
            resolve(res)
          }
        } else if (res.statusCode == 500) {
          wx.showToast({
            title: '后台异常',
            icon: 'none'
          })
        }
      },
      fail: function (res) {
        wx.hideLoading()
        wx.showToast({
          title: res.errMsg,
          image: '/static/icon/error.png'
        })
      }
    })
  })
  return promise
}
module.exports = apiRequest;
  1. 在api文件中统一处理api请求
import httpRequest from './httpRequest'
export const notaryHistoryPage(params) {
  return httpRequest({ url: '/api/*******', params }).then(res => res)
},
  1. 页面使用
var api = require('../../api/api.js').default;
Page({
	show:function() {
		let params = {
			id:1
		}
		api.notaryHistoryPage(params).then(res=>{}).catch(res=>{})
	}
})



二、例子2:使用 Promise 封装 wx.request

我们大部分网站都是用 cookie 来维护登录状态的,但是小程序是无法用 cookie 来维护登录状态的,那么我们先获取请求头的 cookie, 然后将 cookie 保存在全局变量当中(相信获取 cookie 肯定没问题吧, 这部分就不展示了)

// wx.request 封装
var app = getApp() 

function wxRequest(url, config, resolve, reject) {
  let { 
    data = {},
    contentType = 'application/json',
    method = 'GET',
    ...other
  } = {...config}
  wx.request({
    url: url,
    data: {...data},
    method: method,
    header: {
      'content-type': contentType,
      'Cookie': app.globalData.cookie  // 全局变量中获取 cookie
    },
    success: (data) => resolve(data),
    fail: (err) => reject(err)
  })
}

module.exports = {
  wxRequest: wxRequest
}


业务对应的配置 js文件

// 用 import 或者 require 引入模块 
import util from '../../../util/util.js'
var Promise = require('../../../plugin/promise.js')    // 请注意 Promise 要手动引入,内测版是自动引入的

// 获取个人信息
const API_USERINFO = "https://www.***/get"
// 获取剩余金额
const API_BALANCE = 'https://www.***/get'
// 获取昨日消费数据
const API_LASTCOST = 'https://www.***/get'


// 获取个人信息事件  
function getUserInfo(data, contentType) {

  var promise = new Promise((resolve, reject) => {
    util.wxRequest(API_USERINFO, { data, contentType }, resolve, reject)
  })

  // return promise
  return promise.then(res => {
    return res.data
  }).catch(err => {
    console.log(err) 
  })
}

// 获取剩余金额事件
function getBalance(data, contentType) {

  var promise = new Promise((resolve, reject) => {
    util.wxRequest(API_BALANCE, { data, contentType }, resolve, reject)
  })

  // return promise
  return promise.then(res => {
    return res.data
  }).catch(err => {
    console.log(err)
  })
}

// 获取昨日消费数据
function getLastCost(data, contentType, method) {

  var promise = new Promise((resolve, reject) => {
    util.wxRequest(API_LASTCOST, { data, contentType, method }, resolve, reject)
  })

  // return promise
  return promise.then(res => {
    return res.data
  }).catch(err => {
    console.log(err)
  })
}

module.exports = {
  getUserInfo: getUserInfo,
  getBalance: getBalance,
  getLastCost: getLastCost
}



三、例子3

  1. http.js
const pubUrl = "http://localhost:3000/api"//这是我要请求的数据接口的公共部分
const http = (options) =>{
  return new Promise((resolve,reject) => {
    wx.request({
      url: pubUrl+options.url,
      method:options.method || 'get',
      data:options.data || {},
      header: options.header || {
        'content-type':'application/x-www-form-urlencoded'
      },
      success:resolve,
      fail:reject
    })
  })
}
export default http
  1. app.js(这里主要是对要请求的接口进行了封装,接口会有很多,放在同一个文件中方便管理)
import http from 'http.js' //引入上面封装好的请求方法
// 获取商品的一级分类,不需要参数
const _getTopCate = () => {
  return http({
    url:'/getcate'
  })
}
//获取商品详情,需要传入参数
const _getDetail = (id) => {
  return http({
    url:'/getgoodsinfo',
    data:{
      id
    }
  })
}
// 将方法导出,实现复用
export default{
  _getTopCate,
  _getDetail
  }
  1. 具体需要请求数据的页面的js文件,如:index.js
import Api from '../../utils/api.js' //首先要引入封装好的上述api文件,路径根据自己文件的位置
Page({
	data:{
    },
    // 因为请求数据的方法用promise封装,所以需要配合async 和 await 来获取到promise中的数据
    async _getCate(){ //在需要请求接口获取数据的方法中调用api中的方法
      let result = await Api._getTopCate();
      console.log(result);
  	},
 	async _getDetail(){
      let result = await Api._getDetail(1);
      console.log(result)
  	}
})
  1. index.wxml
<view bindtap="_getCate">获取一级分类</view> //点击会触发上述js中的_getCate()事件,然后调用封装的接口获取到数据
<view bindtap="_getDetail">请求数据商品详情</view>



四、例子4

在小程序里面创建一个公共目录http,里面设置公共访问的url、地址环境。

然后在http目录下面创建env.js。

//commonJs预览 --- node.js采用的就是该规范	
	//什么是common.js规范:每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、
	//函数、类,都是私有的,对其他文件不可见。
	//这里使用的接口呢都是自己模拟的,亲么可以根据自己的需求进行添加
module.exports={
	//开发环境的url
	dev:{
		baseUrl:"http://localhost:3000"
	},
	//测试环境url
	test:{
		baseUrl:"http://www.test.com"
	},
	//线上环境url
	prod:{
		baseUrl:'https://api.it120.cc'
	}
}

继续在http目录下面创建一个request.js文件来二次封装wx.request。

// 引入env中的url
const { baseUrl } = require('./env.js').prod; 
//在这里添加我们的专业域名
const subDomain = 'xxx';
	/*
	 *二次封装wx.request
	 * 
	 */
module.exports = {
    /**
     * 二次封装wx.request
     * {String }url:请求的接口地址
     * {String} method:请求方式 GET,POST....
     * {Object} data:要传递的参数
     * { boolean }isSubDomain:表示是否添加二级子域名 true代表添加, false代表不添加
     */
    request: (url, method, data, isSubDomain) => {
        console.log('这是我封装的ajax请求', baseUrl);
      	//这里使用ES6的写法拼接的字符串
        let _url = `${baseUrl}/${isSubDomain ? subDomain: '' }${url}`;
        console.log(_url);
        return new Promise((resolve, reject) => {
			wx.showLoading({
				title: '正在加载',
			});
            wx.request({
                url: _url,
                data: data,
                method: method,
                header: {
                    'content-type': 'application/x-www-form-urlencoded',
                },
                success: (res) => {
                    console.log('从接口获取到的数据', res);
					let { code } = res.data;
					if(code===0) {
						resolve(res.data);
						wx.hideLoading();
					}else {
						wx.showToast({
							title: '数据请求错误',
						})
					}
                },
				fail() {
					reject('接口有误,请检查')
				}
            });
        });
    },
}

http目录下面在创建一个api.js文件来封装我们的reuest请求。

//引入封装的reuest请求
const { request } = require('./request.js')
//基于业务封装的接口
module.exports={

	/* 轮播图 */
	banners:()=>{
		return request(','GET',{},true);
	},
	/* 封装商品列表的方法 */
	getGoodsList:()=>{
		return request('要请求的路径','请求方式|GET|POST',{要携带的参数},是否添加子域名 |true|false);
	},
	/* 添加商品收藏 */
	addGoodsFav: (goodsId, token)=>{
		return request('要请求的路径', 'POST', { goodsId:goodsId, token:token},true);
	},
	/* 获取商品的分类 */
	getGoodsCate:()=>{
		return request('要请求的路径','GET',{},true);
	}
}

然后再需要的js页面引入就ok了!

const { getGoodsList  } = require('../../http/api.js')
	//定义一个点击事件来测试我们请求的接口
	onbBn() {
		// getGoodsList();
		// addGoodsFav();
		// getGoodsCate()
		console.log('这是我们要测试的接口',getGoodsCate());
		//请求后抛出
		banners().then(res => {
			console.log('终于等到你',res);
		})



五、例子5

  1. 在与pages同级目录下新建http文件夹:

    在这里插入图片描述
  2. 在http文件夹下新建env.js文件,搭建环境:
module.exports={
  //开发环境
  dev:{
    baseUrl:'http://127.0.0.1:8080'
  },
  //生产环境
  prod:{
    baseUrl:'https://api.it120.cc'
  },
  //测试环境
  test:{
    baseUrl:'https://api.1909A.com'
  }
}
  1. 在http文件夹下新建request.js文件,进行接口封装的操作:
const { baseUrl } = require('./env.js').prod
const vipUrl = "sbq"
module.exports = {
  // request是一个函数,封装了request,其中的参数不填的话就会有默认值
  request:function(url,method="GET",data={},isSubDomain=true){
    //把正确的请求地址拼接起来
    let fullurl = `${baseUrl}/${isSubDomain?vipUrl:""}/${url}`
    //Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
    return new Promise((resolve,reject)=>{
        wx.request({
          url: fullurl,
          method,
          data,
          header:{
            //此处的头部信息要注意接口文档
            "content-type":"pplication/x-www-form-urlencoded"
          },
          //成功回调
          success(res){
            if(res.statusCode === 200 && res.data.code===0){
              //返回的数据
              resolve(res.data.data)
            }else{
              console.log("接口有问题")
            }
          },
          //失败回调
          fail(){
            console.log("接口问题")
          }
        })
    })
  }
}
  1. 在http文件夹下新建api.js文件,就是项目中用到的各种业务接口的封装(例举商品列表接口):
const {request} = require('./request.js')
module.exports={
  // 商品列表接口
  goodsItem:()=>{
    return request("shop/goods/list","GET","",true)
  }
}
  1. 然后在对应的组件里面直接调用就可以:
// components/xhy_goodItem/xhy_goodItem.js
const { goodsItem }=require('../../http/api.js')
Component({
  //组件的生命周期
  lifetimes: {
    created() {
      this.getData();
    },
  },
  /**
   * 组件的初始数据
   */
  data: {
    goodItem: []
  },
  /**
   * 组件的方法列表
   */
  methods: {
    getData() {
      goodsItem().then(res=>{
          this.setData({
            goodItem:res
        })
      })
    }
  }
})
  1. 拿到数据,正常渲染页面就可以了。



版权声明:本文为JxufeCarol原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。