axios 数据请求二次封装及实战案例

axios 数据请求二次封装及实战案例,第1张

目录

1、网络请求

2、项目实战应用


1、网络请求

项目中使用 axios 进行网络请求,Vue 脚手架默认没有安装,需要自行安装才能使用。

安装 ( 生产环境依赖 )  "axios": "^0.24.0"

 npm i -S axios 

设置统一请求域名

反向代理 可以进行 跨域 解决

在项目根目录下面创建一个 vue.config.js 文件,写下如下代码

Vue 之 vue.config.js 配置文件_Mr.小灰狼_随笔-CSDN博客_vue.config.js

module.exports = {
  devServer: {
    overlay: false,
    // vue 项目代理请求
    proxy: {
      // 规则
      // axios 中相对地址开头的字符串
      '/api': {
        // 把相对地址中的域名 映射到 目标地址中
        // localhost:8080 => localhost:3000
        target: 'http://localhost:3000',
        // 修改 host 请求的域名为目标域名
        changeOrigin: true,
        // 请求 uri 和目标 uri 有一个对应关系
        // 请求 /api/login ==> 目标 /v1/api/login
        pathRewrite: {
          '^/api': '/v1/api'
        }
      }
    }
  }
}

代理配置 :

这里 , 此处 配置 反向代理 文件内 会有一个 小坑 : 

因为 匹配 的 规则 为  express.use  模糊匹配 , 匹配成功后就会停止向下匹配了 ,

所以匹配的 请求前缀 尽量 不要一样 ,  

比如 你写的  ' / api '   ,  只要你的请求地址内存在  / api  , 它在匹配上之后就会走对象内的程序代码了 , 就不会再向下执行 , 

所以为了预防此问题 , 所以 最好是把 你的 请求前缀 改成  ' ^/api '  ( 以 /api 开头的 )

这样的写法会更严谨 , 防止模糊匹配钻了漏洞

否则即使你下面 再怎么写的 pathRewrite ( 路径重写 ) , 也会失去效果 , 将你的重写路径依旧会带在你的请求地址里 , 并没有给过滤掉 , 导致请求一直 404 失败

所以 , 我们一是要注意咱们的 请求前缀不要一样 ,

二就是我们  最好 将前缀的写法写的更加严谨一些 

 网络请求模块化 : 


2、项目实战应用

二次封装 axios

项目  /  src  /  utils  /  request.js

// 导入 axios
import axios from "axios";
import { Message } from "element-ui";
// import env from '@/config/environment'
import Vue from "vue";

// 全局的 axios 默认值
// 设置请求的基础域名
// axios.defaults.baseURL = process.env.DW_API_URL
// 请求超时时间
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;

// post 请求头
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'

console.log(process.env, "VUE_APP_URL");
const service = axios.create({
  // baseURL: '/dev-api/', 设置基础路径
  // axios 中请求配置有 baseURL 选项,表示请求 URL 公共部分
  // baseURL: process.env.VUE_APP_BASE_URL,    // url = base url + request url
  // 请求超时时间
  // timeout: env.envTimeout,
  timeout: 10000, // request timeout 设置最大响应时间,10秒
});

// request 请求拦截器
service.interceptors.request.use(
  (config) => {
    // config.timeout = 10000
    return config;
  },
  (error) => {
    console.log("request-error:" + error); // for debug
    return Promise.error(error);
  }
);

// response 响应拦截器
service.interceptors.response.use(
  (response) => {
    if (response.status === 200) {
      return response.data;
    } else {
      return Promise.reject(response);
    }
  },
  (error) => {
    // 服务器状态码不是200的情况
    let { message } = error;
    if (message.includes("Network Error")) {
      message = "后端接口连接异常";
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      const code = message.substr(message.length - 3);
      if (code === "401" || code === "403") {
        message = null;
        if (code === "401") {
          // msgBoxNoLogin();
        } else if (code === "403") {
          // msgBoxNoRole();
        }
      } else {
        message = "系统接口" + message.substr(message.length - 3) + "异常";
      }
    }
    if (message != null) {
      Message.error({
        message: message,
      });
    }
    return Promise.reject(error);
  }
);

// response 响应拦截器
/* service.interceptors.response.use(
  (response) => {
    console.debug("response");
    console.debug(response);
    if (response.status === 200) {
      const { data } = response;
      if (data.hasOwnProperty("resultCode")) {
        if (data.resultCode === 401) {
          msgBoxNoLogin();
        } else if (data.resultCode === 403) {
          msgBoxNoRole();
        } else if (data.resultCode !== 200) {
          let message = `异常码:${data.resultCode}`;
          if (data.hasOwnProperty("resultMsg")) {
            message = `${data.resultMsg},异常码:${data.resultCode}`;
          }
          msgError(message);
        }
      }
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  (error) => {
    // 服务器状态码不是200的情况
    console.log("err" + error);
    let { message } = error;
    if (message.includes("Network Error")) {
      message = "后端接口连接异常";
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      const code = message.substr(message.length - 3);
      if (code === "401" || code === "403") {
        message = null;
        if (code === "401") {
          msgBoxNoLogin();
        } else if (code === "403") {
          msgBoxNoRole();
        }
      } else {
        message = "系统接口" + message.substr(message.length - 3) + "异常";
      }
    }
    if (message != null) {
      msgError(message);
    }
    return Promise.reject(error);
  }
); */

// Vue.prototype.$http = service;

// export default service;

/**
 * 封装后的 ajax post 方法
 *
 * @param {string} url 请求路径
 * @param {object} data 请求参数
 * @param {object} params 用户自定义设置
 * @returns
 */
// GET 请求方法
export const get = (url, params = {}) => {
  let str = "?";
  Object.keys(params).forEach((item) => {
    str += `${item}=${params[item]}&`;
  });
  str = str.slice(0, -1);
  return httpres.get(url + str);
};

// POST 请求方法
export const post = (
  url,
  data = {},
  config = {
    "Content-Type": "application/json",
  }
) => service.post(url, data, config);

模块化拆分

项目  /  src  /  config  /  api  /  listConfig.js

/* 网络 api 接口的基础配置 */
// 网络请求 的 地址信息
export default {
  getMattersList: '/api/survey/surveylist',    // 列表页所有事项数据
  saveSurveyName: '/api/surveyDesign/xxxx',    // 保存问卷名称
  saveAllQuestion: '/api/xxxxxxx/xxxxxxxx',    // 新建保存接口(全部)
  selectSurveyDetial: '/xxx/xxxxxxx/xxxxx',    // 预览
  xxxxXxxxxx: 'xxxxxxx/xxxxxxxxxx/xxxxxxx',    // XXXXXXXX
  
}

项目  /  src  /  config  /  environment.js

/ *  网站环境配置  * /

export default {

    envTimeout :  10000 , 

}


项目  /  src  /  api  / listApi.js

/* 网络 api 接口 */
// 请求网络方式
// 导入封装好的 请求方法
import { get, post } from '@/utils/request'
// 导入网络请求的地址信息
import config from '@/config/api/listConfig'

// 问卷事项列表
export const getMattersListApi = async (data) => {
  let ret = await post(config.getMattersList, data)
  return ret
}

// list 列表页面请求接口
export const getListApi = async (data) => {
  let ret = await get(config.list, data)    // 推荐
  return ret
}

// 保存问卷列表
export const saveSurveyName = async (data) => {
  let ret = await get(config.saveSurveyName + `?SurveyName=${data}`)  // 不推荐
  return ret
}

// 新建问卷保存接口(全)
export const saveAllQuestion = async (data) => {
  let ret = await post(config.saveAllQuestion, data)
  return ret
}

// XXXXXXX
export const XXXXXXXXXXXXX = async (data) => {
  let ret = await get/post(config.XXXXXXXX, data)
  return ret
}

Vue 组件内使用

 项目  /  src  /  views  /  home  /  index.vue





欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/997138.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存