• axios封装


    不要过度封装!封装一个最简单的Axios! - 掘金 (juejin.cn)

    1 初始化 axios 实例

    通过 create 方法我们得到了一个 axios 的实例,该实例上有很多方法,比如拦截器等等。我们创建实例的时候可以配置一些基础设置,比如基础请求地址,请求超时等等。

    1. // 创建 axios 请求实例
    2. const serviceAxios = axios.create({
    3. baseURL: "", // 基础请求地址
    4. timeout: 10000, // 请求超时设置
    5. withCredentials: false, // 跨域请求是否需要携带 cookie
    6. });

    2 设置请求拦截

    我们在发送请求的时候可能需要携带一些信息在请求头上,比如 token 等,所以说我们就需要将请求拦截下来,处理一些我们的业务逻辑。

    1. // 创建请求拦截
    2. serviceAxios.interceptors.request.use(
    3. (config) => {
    4. // 如果开启 token 认证
    5. if (serverConfig.useTokenAuthorization) {
    6. config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
    7. }
    8. // 设置请求头
    9. if(!config.headers["content-type"]) { // 如果没有设置请求头
    10. if(config.method === 'post') {
    11. config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
    12. config.data = qs.stringify(config.data); // 序列化,比如表单数据
    13. } else {
    14. config.headers["content-type"] = "application/json"; // 默认类型
    15. }
    16. }
    17. console.log("请求配置", config);
    18. return config;
    19. },
    20. (error) => {
    21. Promise.reject(error);
    22. }
    23. );

    3 设置响应拦截

    axios 请求的返回结果里面包含了很多东西,我们的业务层面通常只需要后端返回的数据即可,所以我们需要设置相应拦截,在响应结果返回给业务层之前做一些操作。

    1. // 创建响应拦截
    2. serviceAxios.interceptors.response.use(
    3. (res) => {
    4. let data = res.data;
    5. // 处理自己的业务逻辑,比如判断 token 是否过期等等
    6. // 代码块
    7. return data;
    8. },
    9. (error) => {
    10. let message = "";
    11. if (error && error.response) {
    12. switch (error.response.status) {
    13. case 302:
    14. message = "接口重定向了!";
    15. break;
    16. case 400:
    17. message = "参数不正确!";
    18. break;
    19. case 401:
    20. message = "您未登录,或者登录已经超时,请先登录!";
    21. break;
    22. case 403:
    23. message = "您没有权限操作!";
    24. break;
    25. case 404:
    26. message = `请求地址出错: ${error.response.config.url}`;
    27. break;
    28. case 408:
    29. message = "请求超时!";
    30. break;
    31. case 409:
    32. message = "系统已存在相同数据!";
    33. break;
    34. case 500:
    35. message = "服务器内部错误!";
    36. break;
    37. case 501:
    38. message = "服务未实现!";
    39. break;
    40. case 502:
    41. message = "网关错误!";
    42. break;
    43. case 503:
    44. message = "服务不可用!";
    45. break;
    46. case 504:
    47. message = "服务暂时无法访问,请稍后再试!";
    48. break;
    49. case 505:
    50. message = "HTTP 版本不受支持!";
    51. break;
    52. default:
    53. message = "异常问题,请联系管理员!";
    54. break;
    55. }
    56. }
    57. return Promise.reject(message);
    58. }
    59. );

    4 vue完整示例

    在 src 下面新建 http 文件夹,用来存储关于 axios 请求的一些文件,然后在 http 文件夹下新建 index.js 文件,用于封装我们的 axios,然后在新建 config 文件夹,主要用来创建配置文件,最后新建一个 api 文件夹,用于集中管理我们的接口。

     index.js 代码:

    1. import axios from "axios";
    2. import serverConfig from "./config";
    3. import qs from "qs";
    4. // 创建 axios 请求实例
    5. const serviceAxios = axios.create({
    6. baseURL: serverConfig.baseURL, // 基础请求地址
    7. timeout: 10000, // 请求超时设置
    8. withCredentials: false, // 跨域请求是否需要携带 cookie
    9. });
    10. // 创建请求拦截
    11. serviceAxios.interceptors.request.use(
    12. (config) => {
    13. // 如果开启 token 认证
    14. if (serverConfig.useTokenAuthorization) {
    15. config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
    16. }
    17. // 设置请求头
    18. if(!config.headers["content-type"]) { // 如果没有设置请求头
    19. if(config.method === 'post') {
    20. config.headers["content-type"] = "application/x-www-form-urlencoded"; // post 请求
    21. config.data = qs.stringify(config.data); // 序列化,比如表单数据
    22. } else {
    23. config.headers["content-type"] = "application/json"; // 默认类型
    24. }
    25. }
    26. console.log("请求配置", config);
    27. return config;
    28. },
    29. (error) => {
    30. Promise.reject(error);
    31. }
    32. );
    33. // 创建响应拦截
    34. serviceAxios.interceptors.response.use(
    35. (res) => {
    36. let data = res.data;
    37. // 处理自己的业务逻辑,比如判断 token 是否过期等等
    38. // 代码块
    39. return data;
    40. },
    41. (error) => {
    42. let message = "";
    43. if (error && error.response) {
    44. switch (error.response.status) {
    45. case 302:
    46. message = "接口重定向了!";
    47. break;
    48. case 400:
    49. message = "参数不正确!";
    50. break;
    51. case 401:
    52. message = "您未登录,或者登录已经超时,请先登录!";
    53. break;
    54. case 403:
    55. message = "您没有权限操作!";
    56. break;
    57. case 404:
    58. message = `请求地址出错: ${error.response.config.url}`;
    59. break;
    60. case 408:
    61. message = "请求超时!";
    62. break;
    63. case 409:
    64. message = "系统已存在相同数据!";
    65. break;
    66. case 500:
    67. message = "服务器内部错误!";
    68. break;
    69. case 501:
    70. message = "服务未实现!";
    71. break;
    72. case 502:
    73. message = "网关错误!";
    74. break;
    75. case 503:
    76. message = "服务不可用!";
    77. break;
    78. case 504:
    79. message = "服务暂时无法访问,请稍后再试!";
    80. break;
    81. case 505:
    82. message = "HTTP 版本不受支持!";
    83. break;
    84. default:
    85. message = "异常问题,请联系管理员!";
    86. break;
    87. }
    88. }
    89. return Promise.reject(message);
    90. }
    91. );
    92. export default serviceAxios;

    config/index.js 代码:

    1. const serverConfig = {
    2. baseURL: "https://smallpig.site", // 请求基础地址,可根据环境自定义
    3. useTokenAuthorization: true, // 是否开启 token 认证
    4. };
    5. export default serverConfig;

    api/user.js 接口调用示例代码:

    1. import serviceAxios from "../index";
    2. export const getUserInfo = (params) => {
    3. return serviceAxios({
    4. url: "/api/website/queryMenuWebsite",
    5. method: "post",
    6. params,
    7. });
    8. };
    9. export const login = (data) => {
    10. return serviceAxios({
    11. url: "/api/user/login",
    12. method: "post",
    13. data,
    14. });
    15. };

    注意:get 请求需要传 params,post 请求需要传 data。

    Vue 文件中调用示例:

    1. import { login } from "@/http/api/user"
    2. async loginAsync() {
    3. let params = {
    4. email: "123",
    5. password: "12321"
    6. }
    7. let data = await login(params);
    8. console.log(data);
    9. }



     5 下面是我项目中用到的配置~~~ 

    1. const serviceAxios = axios.create({
    2. baseURL: "", // 基础请求地址
    3. // 如 baseURL: baseUrl.apiBaseUrl, url = base url + request url
    4. timeout: 10000, // 请求超时设置
    5. withCredentials: false, // 跨域请求是否需要携带 cookie
    6. });
    7. // 添加请求拦截器
    8. service.interceptors.request.use(
    9. function (config) {
    10. // 判断是否存在token,如果存在的话,则每个http header都加上token
    11. let appToken = store.state.app.appToken
    12. if (appToken) {
    13. config.headers['AppToken'] = appToken
    14. } else {
    15. config.headers['AppToken'] = window.localStorage.getItem('AppToken')
    16. }
    17. return config
    18. },
    19. function (error) {
    20. // 对请求错误做些什么
    21. return Promise.reject(error)
    22. }
    23. )
    24. // 添加响应拦截器
    25. service.interceptors.response.use(
    26. function (response) {
    27. let contentType = response.headers['content-type']
    28. if (typeof contentType != 'undefined' && contentType.includes('application/octet-stream')) {
    29. return response.data
    30. }
    31. let { code, message, content } = response.data
    32. switch (code) {
    33. case 500000:
    34. Toast({ message: message, forbidClick: true })
    35. return Promise.reject(content)
    36. //登录已过期
    37. case 100003:
    38. Toast({ message: message, forbidClick: true })
    39. toLogin()
    40. return Promise.reject(content)
    41. //未登录
    42. case 100004:
    43. Toast({ message: message, forbidClick: true })
    44. toLogin()
    45. return Promise.reject(content)
    46. //未绑定银行卡
    47. case 100005:
    48. Toast({ message: message, forbidClick: true })
    49. router.replace({ path: '/notice' })
    50. return Promise.reject(content)
    51. //未实名认证
    52. case 100006:
    53. Toast({ message: message, forbidClick: true })
    54. router.replace({ path: '/notice' })
    55. return Promise.reject(content)
    56. default:
    57. return Promise.resolve(content)
    58. }
    59. },
    60. function (error) {
    61. return Promise.reject(error)
    62. }
    63. )

  • 相关阅读:
    pytest集成allure报告(allure安装及配置以及如何实现集成)
    10道不得不会的Docker面试题
    MathJax公式编辑示例
    面试算法47:二叉树剪枝
    Vue3学习记录——(7) 异步加载defineAsyncComponent与Suspense组件
    TI mmWave radar sensors Tutorial 笔记 | Module 2: The phase of the IF signal
    将Long类型转化为IP字符串
    tep完整教程帮你突破pytest
    Transformer架构
    全球创见者共话企业韧性 金蝶“数字员工”惊艳亮相
  • 原文地址:https://blog.csdn.net/m0_66051368/article/details/125463681