分享axios+signalr简单封装示例

Ajax Axios

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

从浏览器创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
超时处理
查询参数序列化支持嵌套项处理
自动将请求体序列化为:
JSON (application/json)
Multipart / FormData (multipart/form-data)
URL encoded form (application/x-www-form-urlencoded)
将 HTML Form 转换成 JSON 进行请求
自动转换JSON数据
获取浏览器和 node.js 的请求进度,并提供额外的信息(速度、剩余时间)
为 node.js 设置带宽限制
兼容符合规范的 FormData 和 Blob(包括 node.js)
客户端支持防御XSRF

SignalR

实时 Web 功能是让服务器代码在可用时立即将内容推送到连接的客户端,而不是让服务器等待客户端请求新数据。SignalR 可用于向 ASP.NET 应用程序添加任何类型的“实时”Web 功能。 虽然聊天通常用作示例,但你可以执行更多操作。 每当用户刷新网页以查看新数据,或页面实现 长时间轮询 以检索新数据时,它都是使用 SignalR 的候选项。 示例包括仪表板和监视应用程序、协作应用程序 (,例如同时编辑文档) 、作业进度更新和实时表单。

SignalR 还支持需要服务器进行高频率更新的全新 Web 应用程序类型,例如实时游戏。

SignalR 提供了一个简单的 API,用于创建服务器到客户端远程过程调用, (RPC) 调用客户端浏览器中的 JavaScript 函数, (和其他客户端平台从服务器端 .NET 代码) 。 SignalR 还包括用于连接管理的 API (例如,连接和断开连接事件) ,以及分组连接。

import axios from 'axios'
import * as signalR from '@microsoft/signalr'

// baseURl 系统默认网址
const baseURl = process.env.VUE_APP_API_URL


/*
 * @session
 * 封装sessionStorage常用方法的对象
 * set: 设置sessionStorage要存储的值
 * get: 从sessionStorage中获取值
 * remove: 从sessionStorage中删除值
 * clean: 清空sessionStorage所有存储值
 */
let session = {
    set: (key, value) => {
        if (typeof value == 'object') {
            window.sessionStorage.setItem(key, JSON.stringify(value));
        } else {
            window.sessionStorage.setItem(key, value);
        }
    },
    get: (key) => {
        var result = window.sessionStorage.getItem(key);
        if (Global.isJsonFormat(result)) {
            return JSON.parse(result);
        } else {
            return result;
        }
    },
    remove: (key) => {
        window.sessionStorage.removeItem(key);
    },
    clean: (key) => {
        window.sessionStorage.clear();
    }
}

/*
 * @storage
 * 封装localStorage常用方法的对象
 * set: 设置localStorage要存储的值
 * get: 从localStorage中获取值
 * remove: 从localStorage中删除值
 * clean: 清空localStorage所有存储值
 */
let storage = {
    set: (key, value) => {
        if (typeof value == 'object') {
            window.localStorage.setItem(key, JSON.stringify(value));
        } else {
            window.localStorage.setItem(key, value);
        }
    },
    get: (key) => {
        var result = window.localStorage.getItem(key);
        if (Global.isJsonFormat(result)) {
            return JSON.parse(result);
        } else {
            return result;
        }
    },
    remove: (key) => {
        window.localStorage.removeItem(key);
    },
    clean: (key) => {
        window.localStorage.clear();
    }
}

/*
 * @axiosMessage
 * 封装axios请求消息提示
 * type: 提示类型|msg: 提示消息|callBack: 消息关闭时的回调函数|settings: 其他配置项
 */
let axiosMessage = (type, msg, callBack, settings) => {
    let defaultSettings = {
        type: type,
        message: msg,
        duration: 2000,
        showClose: true,
        onClose: callBack ? callBack : null
    };
    if (settings && typeof settings == 'object') {
        for (let p in settings) {
            defaultSettings[p] = settings[p];
        }
    }
    Message(defaultSettings);
}

/*
 * @publicAxiosRequest
 * 封装公用的axios请求处理方法
 * params: 请求参数|axiosFunc: axios请求|callBack: 请求成功执行的回调函数|closeLoading: 是否开启Loading效果
 */
let publicAxiosRequest = (params, axiosFunc, callBack, closeLoading) => {
    Global.isLoadingOpened = typeof closeLoading == 'undefined' ? true : closeLoading;
    axiosFunc(params).then((res) => {
        let { code, data, message } = res;
        if (code >= 200 && code < 300) {
            callBack(data, message);
        } else {
            let requestMsg = '';
            if (typeof message == 'object') {
                for (let key in message) {
                    requestMsg += message[key].join('、');
                }
            } else {
                requestMsg = message;
            }
            Global.axiosMessage('error', requestMsg, Global.endLoading);
        }
    }).catch((e) => {
        Global.endLoading();
        console.info(e);
    });
}

// 记录响应错误提示次数
let errorCount = 0

/*
 * axios请求拦截
 */
axios.interceptors.request.use(
    config => {
        // 添加取消请求
        config.cancelToken = new axios.CancelToken(cancel => {
            store.commit('PUSH_TOKEN', { cancelToken: cancel });
        });
        // 判断是否开启Loading效果
        if (Global.isLoadingOpened) {
            Global.startLoading();
        }
        // 配置token信息
        if (Global.storage.get('requestToken')) {
            config.headers.Authorization = 'Bearer ' + Global.storage.get('requestToken');
        }
        return config;
    },
    error => {
        return Promise.reject(error);
    }
)

/*
 * axios响应拦截
 */
axios.interceptors.response.use(
    response => {
        // 请求成功之后必须恢复isLoadingOpened为true
        if (!Global.isLoadingOpened) {
            Global.isLoadingOpened = true;
        }
        // 请求成功之后必须恢复isLoadingClosed为true
        if (!Global.isLoadingClosed) {
            Global.isLoadingClosed = true;
        }
        if (Global.isLoadingClosed) {
            setTimeout(() => {
                Global.endLoading();
            }, 200);
        }
        return response;
    },
    error => {
        // 判断是否是被取消请求的响应错误
        if (axios.isCancel(error)) {
            // 中断promise链接
            return new Promise(() => {
                // 判断是否有Loading加载效果没有关闭
                if (Global.requestLoading) {
                    setTimeout(() => {
                        Global.endLoading();
                    }, 200);
                }
            });
        } else {
            if (error.response && error.response.status) {
                errorCount++;
                let msg = '';
                switch (error.response.status) {
                    case 404: // 请求不存在
                        msg = '请求不存在,请重新登录';
                        break;
                    case 417: // 没有操作权限
                        msg = '没有操作权限,请联系管理员设置';
                        break;
                    case 500: // 服务器异常
                        msg = '服务器异常,请稍后操作';
                        break;
                    default: // 其他错误
                        msg = error.response.data.message;
                }
                // 多个错误提示时只弹出一个提示框
                if (errorCount < 2) {
                    Global.confirmBox('warning', msg, '提示', () => {
                        Global.session.clean();
                        Global.storage.clean();
                        window.location.href = window.location.origin + '/#/';
                    });
                }
                return Promise.reject(error.response);
            }
        }
    }
)

// 初始化signalr
export const initSignalr = (func1) => {
    const signalrAddress = process.env.VUE_APP_API_URL,
        AccessToken = Global.storage.get('requestToken'),
        TenantId = Global.storage.get('companyId') ? Global.storage.get('companyId') : '';
    let connection = new signalR.HubConnectionBuilder()
        .withUrl(signalrAddress + '/hubs/chathub?access_token=' + AccessToken + '&TenantId=' + TenantId) // signalr连接地址
        .withAutomaticReconnect({ nextRetryDelayInMilliseconds: () => 50000 }) // 断开自动重连
        .build();
    // 监听断开重连
    connection.onreconnected(connectionId => {
        console.log('重新连接成功', connectionId);
    });
    // 监听连接关闭
    connection.onclose(err => {
        console.log('连接关闭', err);
    });
    // 注册后端调用的方法(接收数据)
    connection.on('ReceiveMessage', func1);
    // 开始连接
    connection.start()
        .then(res => {
            console.info('%c连接成功', 'color: #03d903');
        })
        .catch(err => {
            console.info('%c连接失败', 'color: #ff0000');
        });
    return connection;
}

// 推送数据给后端
export const sendMessage = (signalr, data) => {
    if (signalr) {
        signalr.send('SendMessage', data)
            .then(res => {
                console.log('推送成功', res);
            });
    }
}

// 关闭signalr
export const closeSignalr = (signalr) => {
    if (signalr) {
        signalr.stop();
        signalr = null;
    }
}

// 【登录】获取token信息
export const userLogin = (params) => { return axios.post(`${REQUEST_URL}/api/login`, params).then(res => res.data) }

export default axios

const Global = {
    baseURl,
    session,
    storage,
    axiosMessage,
    publicAxiosRequest
}

export default Global

参见:

axios - npm

Axios中文文档 | Axios中文网

@microsoft/signalr - npm

SignalR 简介 | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/440064.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kafka 可视化工具

kafka可视化工具 随着科技发展&#xff0c;中间件也百花齐放。平时我们用的redis&#xff0c;我就会通过redisInsight-v2 来查询数据&#xff0c;mysql就会使用goland-ide插件来查询&#xff0c;都挺方便。但是kafka可视化工具就找了半天&#xff0c;最后还是觉得redpandadata…

一招教你优化TCP提高大文件传输效率

在当今企业的数据传输实践中&#xff0c;传统的传输控制协议&#xff08;TCP&#xff09;在处理大型文件传输时&#xff0c;其固有的可靠性和复杂性有时会导致效率不足。为了提升大文件传输的效率&#xff0c;对TCP进行优化成为了一个关键任务。 TCP传输的可靠性是其核心优势&a…

Kubernetes-2

Kubernetes学习第二天 k8s-21、Kubernetes的核心组件2、pod2.1、什么是pod 3、3种启动pod的方式3.1、命令行启动pod3.1.1、执行下面命令&#xff0c;背后发生了什么&#xff1f; 3.2、启动一个pod背后发生了什么3.3、使用yml文件3.3.1、标准的pod3.3.2、使用部署控制器启动pod3…

windows部署腾讯tmagic-editor01-Hello world

之前写过一篇使用yarn实现的https://blog.csdn.net/qq_36437991/article/details/133644558&#xff0c;后面的两个没有写&#xff0c;这次准备重新实现 环境 pnpm 8.15.1 node 18.19.0 创建vue项目 pnpm create vitecd hello-world pnpm install执行pnpm dev启动项目 安…

[PTA] 分解质因子

输入一个正整数n&#xff08;1≤n≤1e15&#xff09;&#xff0c;编程将其分解成若干个质因子&#xff08;素数因子&#xff09;积的形式。 输入格式: 任意给定一个正整数n&#xff08;1≤n≤1e15&#xff09;。 输出格式: 将输入的正整数分解成若干个质因子积的形式&#…

TypeScript 基础(一)

目录 一、概述 二、开发环境 三、数据类型 1.boolean 2.number 3.string 4.Array 5.type 6.tuple 7.enum 8.any 9.null / undefined 10.never 11.object 结束 一、概述 TypeScript 是一种由微软开发的开源编程语言。它是 JavaScript 的一个超集&#xff0c;这意…

正则表达式-分组

1、oracle-正则表达式&#xff1a;将09/29/2008 用正则表达式转换成2008-09-29 select regexp_replace(09/29/2008, ^([0-9]{2})/([0-9]{2})/([0-9]{4})$, \3-\1-\2) replace from dual; 解析&#xff1a;regexp_replace-替换&#xff0c; 第一个参数&#xff1a;需要进行处…

5个实用的PyCharm插件

大家好&#xff0c;本文向大家推荐五个顶级插件&#xff0c;帮助开发人员提升PyCharm工作流程&#xff0c;将生产力飞升到新高度。 1.CodiumAI 安装链接&#xff1a;https://plugins.jetbrains.com/plugin/21206-codiumate--code-test-and-review-with-confidence--by-codium…

项目的搭建与配置

vue create calendar_pro 选择如下配置选项 安装 vue3 支持 vue add vue-next package.json 关闭 eslint 检测。 vue.config.js 配置跨域同源策略。 const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpileDependencies: true,devServe…

【uni-app】condition 启动模式配置,生产环境无效,仅开发期间生效

在小程序开发过程中&#xff0c;每次代码修改后&#xff0c;都会启动到首页&#xff0c;有时非常不方便&#xff0c;为了更高效的开发&#xff0c;有时需要模拟直接跳转到指定的页面&#xff0c; 操作方法如下&#xff1a; 在pages.joson里面配置下列代码&#xff1a; "…

【自然语言处理六-最重要的模型-transformer-上】

自然语言处理六-最重要的模型-transformer-上 什么是transformer模型transformer 模型在自然语言处理领域的应用transformer 架构encoderinput处理部分&#xff08;词嵌入和postional encoding&#xff09;attention部分addNorm Feedforward & add && NormFeedforw…

24/03/07总结

esayx: 贪吃蛇: #include "iostream" #include "cmath" #include "conio.h" #include "easyx.h" #include "time.h" #define NODE_WIDTH 40 using namespace std; typedef struct {int x;int y; }node; enum direction /…

Python笔记|基础算数运算+数字类型(1)

重新整理记录一下python的基础知识 基础运算符 、-、*、/ &#xff1b;括号 ()用来分组。 >>>2 2 4 >>>50 - 5*6 20 >>>(50 - 5*6) / 4 5.0 >>>8 / 5 1.6向下取整除法&#xff1a;向下舍入到最接近的整数的数学除法。运算符是 //。比如1…

力扣面试经典150 —— 6-10题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 6. [中等] 轮转…

谷歌浏览器打包扩展插件,提示清单文件缺失或不可读取

今天想把谷歌浏览器的扩展打包一下&#xff0c;放到我虚拟机的谷歌浏览器&#xff0c;但是一直打包不成功。 问题 打包扩展程序错误 提示‘清单文件缺失或不可读取’ 原因 路径没有选择正确&#xff01; 解决办法 1.首先找到google浏览器的安装路径。在谷歌浏览器地址栏输…

穷人想赚钱该怎么选打工VS创业?2024年如何把握新机遇?

在贫穷的困境中&#xff0c;打工与创业似乎成为了两条截然不同的道路&#xff0c;摆在每一个渴望改变命运的人面前。然而&#xff0c;这并非简单的选择题&#xff0c;而是一场关于勇气、智慧与机遇的较量。打工&#xff0c;对于许多人来说&#xff0c;是稳定且相对安全的收入来…

XSS靶场-DOM型初级关卡

一、环境 XSS靶场 二、闯关 1、第一关 先看源码 使用DOM型&#xff0c;获取h2标签&#xff0c;使用innerHTML将内容插入到h2中 我们直接插入<script>标签试一下 明显插入到h2标签中了&#xff0c;为什么不显示呢&#xff1f;看一下官方文档 尽管插入进去了&#xff0…

Java后端八股笔记

Java后端八股笔记 Redis八股 上两种都有可能导致脏数据 所以使用两次删除缓存的技术&#xff0c;延时是因为数据库有主从问题需要更新&#xff0c;无法达到完全的强一致性&#xff0c;只能达到控制一致性。 一般放入缓存中的数据都是读多写少的数据 业务逻辑代码&#x1f44…

双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的技术应用

原文链接&#xff1a;双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的技术应用https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&tempkeyMTI2MF9DVWNrMFpvV1d3RGxBZUE2QXJBRnI1NEJkcVhzRFZwakRqYXhhVFQzQnh1MVhJcy1laWh6Nmd4R…

[密码学]入门篇——加密方式

一、概述 加密方法主要分为两大类&#xff1a; 单钥加密&#xff08;private key cryptography&#xff09;&#xff1a;加密和解密过程都用同一套密码双钥加密&#xff08;public key cryptography&#xff09;&#xff1a;加密和解密过程用的是两套密码 历史上&#xff0c…