openx-js-sdk
v0.1.6
Published
**openx-js-sdk** 面向 CNKI 研学、授权等业务场景,是一个轻量级、可扩展的前端通用 SDK,封装了:
Readme
openx-js-sdk
1. SDK 介绍
openx-js-sdk 面向 CNKI 研学、授权等业务场景,是一个轻量级、可扩展的前端通用 SDK,封装了:
- 🔑 JWT 自动获取 & 自动续期
- 🌍 统一接口代理(development/test/production)
- ⚙️ get/post 请求封装
- 🚦 可配置的全局响应处理器
- 💡 IP 获取、Cookie 工具、本地缓存管理
- 📊 埋点(Tracker)按需加载与 AppId 统一管理
业务开发者只需使用公开 API,无需关心底层网络、身份态、埋点加载等逻辑。
📌 版本历史
v0.1.6 – 2026-03-06
- 新增 putAction、updateAction、deleteAction 请求方法。
v0.1.5 – 2026-03-04
- 新增请求配置项
skipJwt(boolean)。 - 允许在发起特定请求(如公开接口、登录注册页)时,通过设置
{ skipJwt: true }显式阻止jwt的自动注入。
v0.1.3 – 2026-03-04
- 基础请求拦截器中增加了
AccessToken头的自动注入逻辑,默认从 Cookie 中读取LID值,若存在则自动添加至请求头AccessToken: <LID>。 - 新增请求配置项
skipAccessToken(boolean)。 - 允许在发起特定请求(如公开接口、登录注册页)时,通过设置
{ skipAccessToken: true }显式阻止AccessToken的自动注入。
v0.1.0 – 2026-01-23
- 增加 platform 用于适配多平台下 jwt 策略
v0.0.30 – 2026-01-13
- userIp 开发模式环境下返回处理
v0.0.29 – 2026-01-11
- 开发环境关闭埋点加载
v0.0.28 – 2026-01-10
- 处理微前端应用下埋点宿主应用与子应用冲突行为
v0.0.27 – 2026-01-09
- 增加 scene 用于业务/宿主场景标识
- 新增 toTrackOpenx 埋点方法,用于 OpenX SDK 内部统一注入业务 / 宿主场景标识
- 去除 overrideTrackerAppId 方法
v0.0.26 – 2025-12-09
- 新增 skipInterceptorsRequest 请求配置项 允许业务方在单个接口级别跳过 interceptorsRequest 对入参的结构化处理。
v0.0.25 – 2025-12-09
- 新增 interceptorResult 方法 允许业务方在请求完成后对最终返回结构进行自定义改造。
- 埋点业务开发环境关闭加载
v0.0.24 – 2025-12-08
- openx 实例新增 logOut 方法用于业务方主动触发退出登录逻辑。
- 针对 5014、5007、重复获取jwt情况,SDK 内部新增自动执行清理机制。
v0.0.23 – 2025-12-08
- getRefreshToken 新增机构账户5019情况返回
v0.0.22 – 2025-12-08
- openx 实例新增 getRefreshToken 方法用于单独设置jwt
v0.0.21 – 2025-12-08
- 新增 interceptorsRequest 请求拦截器钩子用于统一处理接口请求拦截
- 原字段 response 已标记为兼容字段,统一替换为 interceptorsResponse
v0.0.20 – 2025-11-30
处理埋点业务多应用 app_id 混合使用问题
v0.0.17 – 2025-11-30
- 处理 jwt 5013 返回数据问题
v0.0.15 – 2025-11-28
- tracker 初次加载队列阻塞问题处理
v0.0.14 – 2025-11-27
- 新增
withCredentials配置项,默认携带,可在跨域或公共接口场景中通过 withCredentials: false 禁止附带 Cookie。
v0.0.13 – 2025-11-24
- 新增
tracker配置项,用于开启埋点管理 - 新增
overrideTrackerAppId配置项,覆盖原有埋点 appId 行为
v0.0.12 – 2025-11-21
- 新增
verifyRealName配置项,用于开启实名认证阻断机制(429001) - 优化内部正则 URL 匹配逻辑,支持
/proxy-sdk-jwt等带短横线的代理路径
2. 安装方式
npm install openx-js-sdk
# 或
yarn add openx-js-sdk
# 或
pnpm add openx-js-sdk3. 快速开始
3.1 初始化(推荐在应用入口处执行)
import openx from 'openx-js-sdk'
openx.config({
appId: '', // 当前应用 AppId(JWT & 埋点)
env: 'test', // development | test | production
verifyRealName: true, // 开启实名认证自动阻断
timeout: 5000, // axios 超时时间,默认 5000ms
tracker: true, // 是否开启埋点(按需加载)
scene: '', // 多场景标识,没有场景需求可为空
interceptorsResponse: (res) => {
// 可选:全局业务响应处理
},
interceptorsRequest: (res) => {
// 可选:全局请求拦截器钩子
config.headers['X-Requested-With'] = ''
return config
},
interceptorsResult(res) {
return res.data // 返回结构可由业务方自行决定
},
proxy: {
/**
* SDK 额外要求的代理配置:
* - 因为 SDK 内部会自动调用 JWT / IP 相关接口,因此业务项目必须提供与 SDK 通信的本地代理前缀
* - /proxy-sdk-jwt /proxy-sdk-ip 前缀只在 development(本地开发)环境下使用
* - 测试 / 生产环境不会使用这些代理,构建后会根据 env 自动转换为 target 真实地址
* - 业务方也可以传入其他接口服务;打包时 SDK 会自动做替换
*/
'/proxy-sdk-jwt': {
// 研学基础代理
target: 'https://xtest.cnki.net/coreapi/api'
},
'/proxy-openx-jwt': {
// 开放平台基础代理
target: 'https://xrtest.cnki.net/openx/admin'
},
'/proxy-sdk-ip': {
target: 'https://xtest.cnki.net/ip'
}
}
})
// ready 会自动获取或刷新 JWT
await openx.ready()4. 请求接口
4.1 GET 请求
const res = await openx.getAction('/proxy-ix/endpoint', {
name: 'charlie'
})4.2 POST 请求
const res = await openx.postAction('/proxy-ix/endpoint', {
name: 'charlie'
})SDK 会自动:
- 携带 JWT
- 处理 JWT 过期自动续期
- 根据 proxy 自动切换 BaseURL
- 对响应进行封装
4.3 支持第三个参数配置 Headers / Timeout 等 Axios 配置
业务方可以为 getAction 与 postAction 传递 第三个参数,用于设置额外的请求配置,例如自定义 Header、超时时间、携带特殊标记字段等。 示例:传入自定义 Headers
const res = await openx.postAction(
'/proxy-ix/endpoint',
{ name: 'charlie' },
{
timeout: 8000,
withCredentials: true,
skipAccessToken: true, // 不参与LID注入
skipJwt: true, // 不参与jwt注入
headers: {
'X-From': 'xai-writing',
'X-Request-ID': 'abc123'
}
}
)5. JWT 管理
5.1 获取当前 JWT
const token = openx.getJwt()5.2 清除 JWT
openx.removeJwt()6. 配置项说明(ConfigOptions)
openx.config({
appId: string, // 当前应用的 appId
env?: 'development' | 'test' | 'production',
verifyRealName?: boolean, // 是否开启实名认证自动阻断
timeout?: number, // axios 超时时间
platform?: number, // 用于适配开放平台 JWT 体系(影响 JWT Key),不影响其他逻辑
withCredentials?: boolean, // 是否默认携带cookie
proxy?: Record<string, any>, // 本地代理配置
scene?: string, // 多场景标识
interceptorsResponse?: (res: any) => any, // 全局请求响应处理
interceptorsRequest?: (res: any) => any, // 全局请求拦截处理
interceptorResult?: (res: any) => any, // 全局返回结构拦截处理
tracker?: boolean
})7. 获取用户 IP
const ip = await openx.getUserIp()SDK 会自动缓存 IP,避免重复请求。
8. 埋点管理(Tracker)
openx-js-sdk 内置埋点模块,采用 按需加载策略(Lazy Load),解决旧项目中必须手动引入 sensors.min.js 的问题。
只有在显式开启埋点时才会自动加载脚本:
tracker: true8.1 tracker 的作用
| 配置 | 行为 |
| -------------------- | ----------------------------------- |
| tracker: false(默认) | 不加载 sensors,不初始化埋点,全程 0 成本 |
| tracker: true | 按需加载 sensors,并提供全局 sta_api 用于事件上报 |
8.2 toTrackOpenx 埋点方法
openx-js-sdk 通过克隆原有埋点能力,提供了一套 SDK 独有的埋点方法,用于上报 SDK 内部行为:
window.sta_api?.toTrackOpenx({
event_id: 'sdk_init'
})通过 toTrackOpenx 上报的事件将:
- 自动注入初始化配置的 scene
- 使用与业务埋点一致的底层埋点 SDK 能力
- 不会影响业务侧 toTrack 的调用与数据结构
8.3 宿主应用已存在埋点配置时的说明
在部分宿主系统中,可能已经对 window.sta_api.toTrack 做过统一封装或二次处理,例如统一注入 app_id、环境标识等:
const originalToTrack = window.sta_api.toTrack
window.sta_api.toTrack = function (params) {
let merged = { ...params }
// 增加排除子应用策略
if (params.track_from !== 'openx-js-sdk') {
merged = {
...params,
app_id: `${appId}${env ? '_' + env : ''}`
}
}
return originalToTrack.call(window.sta_api, merged)
}
为什么需要区分 track_from
openx-js-sdk 的埋点属于 平台 SDK 内部行为,其语义与业务埋点不同:
- SDK 埋点用于观测 能力使用情况、稳定性与接入状态
- 业务埋点用于统计 业务行为与用户路径
因此,不建议在宿主应用的统一埋点封装中,对 SDK 埋点强制覆盖 app_id 或业务相关字段。
推荐做法
- 通过
track_from === 'openx-js-sdk'明确识别 SDK 埋点 - 业务侧埋点与 SDK 埋点共用底层 Sensors 能力,但 保持语义隔离
- SDK 埋点不参与业务
app_id的二次注入逻辑
8.4 设计说明(平台级约定)
在微前端(如乾坤)架构下,Sensors Web SDK 采用全局单实例模型。
openx-js-sdk不尝试创建独立的埋点实例,而是通过明确的埋点来源标识(track_from)与场景字段,实现父 / 子应用及 SDK 内部行为的清晰区分。
该设计确保:
- 父应用与子应用可长期共存
- 不引入 iframe 或额外运行环境
- 不破坏宿主系统现有埋点策略
- SDK 可作为平台能力持续演进
9. 退出登录管理
sdk 提供统一的 退出登录 方法,用于在业务系统中安全清理用户登录态,包括: 清理所有与研学平台相关的 Cookie 清理 JWT(通过 cnki-x-jwt 管理的 token) 返回结构化结果,便于业务层进行后续处理(如跳转登录页、弹出提示等)
- 示例:业务方调用
import openx from 'openx-js-sdk'
const result = openx.logOut()
if (result.code===0) {
console.log('用户已退出登录', result)
// 可选:跳转登录页
// window.location.href = '/login'
} else {
console.error('退出登录失败', result.error)
}- 退出成功返回示例
{
"code": 0,
"message": "退出登录成功",
"clearedCookies": [
"LID",
"AID"
],
"clearedJwtKey": "appId"
}10. 完整示例
import openx from 'openx-js-sdk'
// 初始化
openx.config({
appId: 'xxx',
env: 'development',
proxy: {},
verifyRealName: true,
tracker: true,
scene: '',
interceptorsResponse: (res) => {
if (res.data.code === 5014) {
console.log('登录过期,业务方自行处理')
}
},
interceptorsRequest: (config) => {
config.headers['X-Requested-With'] = ''
return config
}
})
await openx.ready()
// 示例请求
const info = await openx.getAction('/proxy-ix/user/getUserInfo',{},{
withCredentials: true,// 单独设置接口携带cookie项
timeout: 10000 // 单独设置接口超时时间
})
console.log(info)11. UMD 使用方式(浏览器直引)
openx-js-sdk 同时提供 UMD 格式构建产物,适用于以下场景:
- 无构建工具的传统页面
- 微前端宿主系统统一注入 SDK
- 第三方系统通过
<script>方式集成 - 乾坤等微前端架构下作为全局基础能力使用
11.1 引入方式
<script src="https://piccachex.cnki.net/openx/sdk/openx-js-sdk-0.0.28.js"></script>引入后,SDK 会自动挂载到全局对象:
window.openx11.2 初始化示例(UMD)
<script>
window.openx.config({
appId: 'xxx',
env: 'production',
tracker: false,
scene: 'X',
verifyRealName: true
})
window.openx.ready().then(() => {
console.log('openx ready')
})
</script>11.3 调用示例
<script>
// GET 请求
window.openx.getAction('/api/user/info').then(res => {
console.log(res)
})
// 获取 JWT
const token = window.openx.getJwt()
</script>11.4 与构建模式的差异说明
| 模式 | 使用方式 |
| --------- | ---------------------------------- |
| ESM / CJS | import openx from 'openx-js-sdk' |
| UMD | window.openx |
无论使用哪种方式,SDK 内部逻辑、配置项与行为保持完全一致。
11.5 微前端(乾坤)场景说明
在微前端(如乾坤)架构下:
openx-js-sdk以 全局单例 形式存在- 宿主应用与子应用 共用同一个
window.openx实例 - SDK 内部状态(JWT、队列、埋点、缓存)统一管理
- 不会因子应用重复加载导致状态冲突
SDK 不依赖 iframe,不创建独立运行环境,适合作为平台级基础能力使用。
