public-client-sdk
v1.2.0
Published
跨端前端通用微内核 SDK - 提供 DEDS 多维动态安全签名、网络拦截器、跨端排他路由锁、跨端持久化缓存、高可用 WebSocket、常用业务格式化工具等 (零 Node 依赖,极小包体,兼容 Uni-app、微信/抖音小程序、Web 与移动端 App)
Maintainers
Readme
public-client-sdk
面向 Uni-app(Web / App / 小程序)、微信小程序、抖音小程序、Web SPA 等前端环境的通用客户端 SDK。
无 Node.js 内置模块依赖,全量打包体积小于 3KB,配合后端 public-sdk 提供接口签名校验、路由并发拦截、多端缓存与长连接封装能力。
前后端协同架构
public-client-sdk 与后端 public-sdk 协同工作,提供端到端的基础通信与安全能力支持:
┌─────────────────────────────────────────────────────────────┐
│ 前端应用集群 (Frontends) │
│ - B端工厂小程序 (factory-mp) - C端商城小程序 (market-mp) │
│ - 平台管理后台 (pc-admin) - 移动端混合 App (App-Plus) │
└──────────────────────────────┬──────────────────────────────┘
│
驱动层: public-client-sdk
(DEDSSigner / UniRequest / UniversalRouter / Storage / Socket)
│
▼ [DEDS 动态加签 / Send 数据规范]
│
后端服务: public-sdk
(SignatureGuard / Http / Send / TokenService / WX)
│
┌──────────────────────────────┴──────────────────────────────┐
│ 后端微服务集群 (ts-server) │
│ - factory-service - market-service - admin-service │
│ - pay-service - ws-service - cron-service │
└─────────────────────────────────────────────────────────────┘| 功能模块 | 前端 SDK (public-client-sdk) | 后端 SDK (public-sdk) | 说明 |
| :--- | :--- | :--- | :--- |
| 接口防篡改与防重放 | DEDSSigner (动态签名发生器) | SignatureGuard (Express 守卫中间件) | 客户端计算动态时间戳与摘要签名,服务端基于时间片窗口及防重放机制完成校验 |
| 统一数据响应与解包 | UniRequestClient / Fetch / Axios | Send.success / Send.fail | 前端自动解包 body.data,统一错误状态码与 401 登录态防抖拦截 |
| 跨端路由并发锁 | UniversalRouter (多端通用 Router) | - | 跳转未完成前拦截后续并发跳转,防止快速连点造成重复打开或页面栈溢出 |
| 多端持久化缓存 | UniversalStorage (多端统一 Storage) | - | 统一多端本地存储接口,支持指定秒级/毫秒级过期时间(TTL) |
| 长连接消息推送 | SocketClient (WebSocket 客户端) | ws-service / Redis PubSub | 内置心跳检测、指数退避重连、页面生命周期事件解绑与离线消息缓冲 |
| 时间漂移校准 | setServerTimeOffset | /common/timestamp | 校准客户端与服务端时间差,保证签名校验时间片对齐与业务倒计时准确 |
安装
npm install public-client-sdk --save核心功能
1. 路由并发拦截 (Router / UniversalRouter)
针对小程序与单页应用在快速连点时可能出现的页面重复打开、页面栈溢出或跳转动画异常问题,Router 在单次跳转完成或报错前,自动拦截并发发起的后续跳转请求。
全局拦截(推荐)
import { Router } from 'public-client-sdk'
// 应用初始化入口 (如 main.js / init.js) 中执行一次
Router.install()
// 拦截全局 uni.navigateTo、uni.redirectTo、uni.switchTab 等路由跳转并发API 显式调用
import { Router } from 'public-client-sdk'
// 1. 保留当前页面跳转 (支持自动格式化 query 对象参数)
await Router.navigateTo('/pages/order/detail', { id: 10086, role: 'cutter' })
// 2. 重定向关闭当前页
await Router.redirectTo('/pages/login/index')
// 3. TabBar 切换
await Router.switchTab('/pages/index/index')
// 4. 关闭所有页面并打开
await Router.reLaunch('/pages/index/index')
// 5. 页面返回
await Router.navigateBack(1)Vue Router 适配
import { Router } from 'public-client-sdk'
import router from './router'
// 绑定 Vue Router 实例
Router.setWebRouter(router)
// 页面内调用同样支持并发拦截与参数序列化
await Router.navigateTo('/user/list', { page: 1, pageSize: 10 })2. 网络请求客户端 (UniRequestClient)
适配 Uni-app、微信小程序 (wx)、抖音小程序 (tt) 与原生 App 环境。
自动注入 DEDS 动态签名与 Token,内置 401 防抖拦截、自动解包与统一错误处理。
import { UniRequestClient } from 'public-client-sdk'
export const request = new UniRequestClient({
baseUrl: 'https://api.yourdomain.com/api',
kernelSeed: 0x5f3759df,
clientFp: 'factory_mp',
unwrapData: true, // 默认 true: 自动解包返回 body.data
getToken: () => uni.getStorageSync('token'),
getFactoryId: () => uni.getStorageSync('activeFactoryId'),
onUnauthorized: (err) => {
uni.removeStorageSync('token')
Router.navigateTo('/pages/login/index')
}
})
// 1. 发起 GET 请求 (自动拼接并清理 undefined 参数)
const list = await request.get('/recruitment/list', { jobType: '车位工' })
// 2. 发起 POST 请求
const res = await request.post('/factory/ticket/accept', { ticketId: 10086 })
// 3. 原样获取完整结构(包含 code, message, timestamp)
const rawRes = await request.raw('/factory/ticket/accept', 'POST', { ticketId: 10086 })
console.log(rawRes.code, rawRes.message, rawRes.data)
// 4. 统一文件上传 (多端兼容)
const uploadRes = await request.upload('/tmp/image.png', '/common/upload')3. Axios 拦截器 (setupPublicSdkAxios)
适用于基于 Axios 的 Web 管理端项目:
import axios from 'axios'
import { setupPublicSdkAxios } from 'public-client-sdk'
const request = axios.create({ baseURL: '/api', timeout: 10000 })
// 挂载 DEDS 签名请求拦截器及响应统一处理
setupPublicSdkAxios(request, {
kernelSeed: 0x5f3759df,
clientFp: 'pc_admin',
getToken: () => localStorage.getItem('admin_token') || '',
onUnauthorized: () => {
localStorage.removeItem('admin_token')
window.location.href = '/login'
}
})
export default request4. 本地缓存 (Storage / UniversalStorage)
统一 Uni-app、微信小程序、抖音小程序与 Web 的本地存储接口,支持指定过期时间(TTL):
import { Storage } from 'public-client-sdk'
// 1. 写入缓存(支持过期时间,单位:秒)
Storage.set('user_profile', { id: 1001, name: '张三' }, { expireSeconds: 3600 })
// 2. 读取缓存(自动反序列化,若已过期则自动清除并返回 null)
const profile = Storage.get('user_profile')
// 3. 删除与清空
Storage.remove('user_profile')
Storage.clear()5. 动态签名 (DEDSSigner)
与后端 public-sdk 的 SignatureGuard 签名算法一致。纯 TypeScript/JavaScript 实现,无 Node.js 内置依赖,支持在小程序与浏览器环境中生成请求头签名:
import { DEDSSigner, setServerTimeOffset } from 'public-client-sdk'
// 1. 校准服务端时间差
setServerTimeOffset(1787279799862)
// 2. 初始化签名器
const signer = new DEDSSigner({
kernelSeed: 0x5f3759df,
clientFp: 'factory_mp'
})
// 3. 计算签名 Headers
const signHeaders = signer.sign({
method: 'GET',
url: '/recruitment/list?jobType=全部',
data: { jobType: '全部' },
token: 'JWT_TOKEN_STRING'
})
console.log(signHeaders)
// {
// 'X-Timestamp': '1787279799862',
// 'X-Nonce': 'assl9x4456asmta6',
// 'X-Client-Fp': 'factory_mp',
// 'X-Signature': '90ca106aee1600af075570c0bd8bfa673e5666e407f66be2e6b6a5812f991cf8bc5a'
// }6. WebSocket 客户端 (SocketClient)
提供支持断线重连与页面生命周期绑定的 WebSocket 封装:
import { SocketClient } from 'public-client-sdk'
export const socket = new SocketClient({
url: 'wss://api.yourdomain.com/ws',
getToken: () => uni.getStorageSync('token')
})
socket.connect()
// 页面生命周期绑定(页面卸载时自动注销监听,防止内存泄漏)
export default {
onLoad() {
socket.bindPage('ticketPage', 'TICKET_UPDATED', (data) => {
console.log('收到工单状态实时推送:', data)
})
},
onUnload() {
socket.unbindPage('ticketPage')
}
}7. 数据格式化与脱敏工具 (format)
import {
fenToYuan,
yuanToFen,
formatDate,
timeAgo,
maskPhone,
maskName
} from 'public-client-sdk'
fenToYuan(1250) // '12.50' (货币分转元)
yuanToFen(12.5) // 1250 (货币元转分)
maskPhone('13812345678') // '138****5678' (手机号脱敏)
maskName('诸葛孔明') // '诸**明' (姓名脱敏)
timeAgo(Date.now() - 60000) // '1分钟前'许可证
ISC License © 2026 yajun.xu
