Skip to content

封装请求

第一步封装拦截器

  • src>lanjieqi>新建 requestlanjie.js
js
/* eslint-disable no-param-reassign */
import qs from "qs";
const baseUrl = "https://jsonplaceholder.typicode.com";
// 拦截器配置
const httpInterceptor = {
  // 拦截前触发
  invoke(options) {
    // 接口请求支持通过 query 参数配置 queryString
    options.url = baseUrl + options.url;
    if (options.query) {
      const queryStr = qs.stringify(options.query);
      if (options.url.includes("?")) {
        options.url += `&${queryStr}`;
      } else {
        options.url += `?${queryStr}`;
      }
    }
    // 非 http 开头需拼接地址
    // 1. 请求超时
    options.timeout = 10000; // 10s
    // 2. (可选)添加小程序端请求头标识
    options.header = {
      ...options.header,
    };
    // 3. 添加 token 请求头标识
    const userStore = { userInfo: { token: "123456" } };
    const { token } = userStore.userInfo;
    if (token) {
      options.header.Authorization = `Bearer ${token}`;
    }
  },
};

export const requestInterceptor = {
  install() {
    // 拦截 request 请求
    uni.addInterceptor("request", httpInterceptor);
    // 拦截 uploadFile 文件上传
    uni.addInterceptor("uploadFile", httpInterceptor);
  },
};

第二步 调用拦截器

  • main.js
js
import { createSSRApp } from "vue";
import App from "./App.vue";
import "virtual:uno.css";
import store from "./store";
import { routeInterceptor } from "./lanjieqi/route";
import { requestInterceptor } from "./lanjieqi/requestlanjie";
export function createApp() {
  const app = createSSRApp(App);
  app.use(store);
  app.use(routeInterceptor);
  app.use(requestInterceptor);
  return {
    app,
  };
}

第三步封装 http 请求类

  • src>utils>http.js
js
export const http = (options) => {
  // 1. 返回 Promise 对象
  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      dataType: "json",
      // #ifndef MP-WEIXIN
      responseType: "json",
      // #endif
      // 响应成功
      success(res) {
        // 状态码 2xx,参考 axios 的设计
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 2.1 提取核心数据 res.data
          resolve(res.data);
        } else if (res.statusCode === 401) {
          // 401错误  -> 清理用户信息,跳转到登录页
          // userStore.clearUserInfo()
          // uni.navigateTo({ url: '/pages/login/login' })
          reject(res);
        } else {
          // 其他错误 -> 根据后端错误信息轻提示
          !options.hideErrorToast &&
            uni.showToast({
              icon: "none",
              title: res.data.msg || "请求错误",
            });
          reject(res);
        }
      },
      // 响应失败
      fail(err) {
        uni.showToast({
          icon: "none",
          title: "网络错误,换个网络试试",
        });
        reject(err);
      },
    });
  });
};

/**
 * GET 请求
 * @param url 后台地址
 * @param query 请求query参数
 * @returns
 */
export const httpGet = (url, query = undefined) => {
  return http({
    url,
    query,
    method: "GET",
  });
};

/**
 * POST 请求
 * @param url 后台地址
 * @param data 请求body参数
 * @param query 请求query参数,post请求也支持query,很多微信接口都需要
 * @returns
 */
export const httpPost = (url, data = {}, query = undefined) => {
  return http({
    url,
    query,
    data,
    method: "POST",
  });
};

http.get = httpGet;
http.post = httpPost;

第四步 使用

html
<template>
  <view @click="gotologin">登录页</view>
</template>

<script setup>
  import { httpGet } from "@/utils/http";
  const gotologin = () => {
    httpGet("/users").then((res) => {
      console.log(res);
    });
  };
</script>

<style scoped></style>