@greentourasia/http
v1.0.1
Published
Greentourasia internal HTTP request library
Readme
🛰️ @greentourasia/http
通用 HTTP 请求封装库(Greentourasia 内部使用)。 为 gta-web / gta-admin 等前端项目提供统一的 网络请求、鉴权、拦截与错误处理 能力。
📦 设计目标
- 解耦传输层与业务层:仅负责 HTTP 通信逻辑,不包含任何业务接口。
- 统一请求行为:统一超时、错误映射、401 自动刷新与请求重放、网络/5xx 自动重试。
- 一次全局初始化:
setupHttp设置 baseURL/刷新端点/CSRF/回调,全局生效。 - 多环境复用:适用于 React / Vue / Node(SSR/脚本)。
- 兼容 HttpOnly Cookie 模式:凭证由浏览器 Cookie 维护,前端不存 token,不注入 Authorization 头。
📁 目录结构(概览)
@gta/http
├─ src/
│ ├─ auth/
│ │ └─ refresh.js # 刷新逻辑(/auth/refresh,HttpOnly 模式)
│ │
│ ├─ config/
│ │ └─ config.runtime.js # 全局运行时配置(setupHttp / setHttpOptions)
│ │
│ ├─ core/
│ │ └─ http.js # Axios 实例、拦截器、自动刷新与重试
│ │
│ ├─ internal/
│ │ └─ errors.js # 内部错误码与工厂函数(仅内部使用)
│ │
│ └─ index.js # 模块导出入口(setupHttp、setHttpOptions、request、refreshOnce)
│
├─ package.json
⚙️ 入口导出(index.js)
export { setupHttp, setHttpOptions } from './config/config.runtime.js';
export { request } from './core/http.js';
export { refreshOnce } from './auth/refresh.js'; // 可选导出(方便外部主动调用)
⚛️ 在 React/Vue 项目中使用
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { setupHttp, setHttpOptions } from '@gta/http';
setupHttp({
baseURL: import.meta.env.VITE_API_BASE, // 统一注入
endpointRefresh: '/auth/refresh', // 后端刷新地址
csrfCookieName: 'csrf_token', // 可选:有就带,减少预检
onAuthError: () => { // 刷新失败/未授权统一处理
window.location.assign('/login');
},
});
// 可选:全局覆盖默认(网络/5xx 自动重试、超时时间)
setHttpOptions({
timeout: 20000,
maxRetries: 3,
retryDelay: 300,
retryMethods: ['get', 'head', 'options'],
});
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode><App /></React.StrictMode>
);
🟩 在 Node(SSR/脚本)中使用
// pages/api/me.js 示例:Next.js API Route,纯 JS 写法
import { setupHttp, request } from '@gta/http';
// 一次性初始化(建议在应用启动时做:比如放到单独的 initHttp.js 里只调用一次)
setupHttp({
baseURL: process.env.API_BASE,
endpointRefresh: '/auth/refresh', // SSR 场景一般不触发;仅为对齐配置
csrfCookieName: 'csrf_token',
onAuthError: () => {
// SSR 通常不自动跳转,这里留空或记录日志即可
// console.warn('auth error on server');
},
});
export default async function handler(req, res) {
try {
const cookie = req.headers.cookie || '';
// 关键点:
// 1) SSR 手动把浏览器 Cookie 透传给后端(Node 不会自动带)
// 2) 关闭 401 自动刷新(skipAuth: true),避免 refreshOnce 去读 document.cookie
const data = await request.get('/user/me', {
headers: { Cookie: cookie },
meta: {
withCreds: false, // Node 环境里没意义,显式关掉
//关键:禁止 401 自动刷新
timeout: 10_000,
},
});
res.status(200).json(data);
} catch (e) {
// 如果后端返回 401,这里直接把状态透传或做 302 跳登录
if (e && (e.code === 'unauthorized' || e.response?.status === 401)) {
res.status(401).json({ code: 'unauthorized', message: '未登录' });
return;
}
res
.status(500)
.json({ code: 'server', message: e?.message || '服务器错误' });
}
}🧪 常见用法速查
🧪 常见用法速查(Cookie-only)
| 能力 | 用法示例 |
|---|---|
| 全局初始化 | setupHttp({ baseURL, endpointRefresh: '/auth/refresh', csrfCookieName: 'csrf_token', onAuthError }) |
| 全局调整默认 | setHttpOptions({ timeout: 20000, maxRetries: 3, retryDelay: 300, retryMethods: ['get','head','options'] }) |
| 发起请求 | await request.get('/users') |
| 单次覆盖超时/重试 | request.post('/save', data, { meta: { timeout: 10000, maxRetries: 5, retryMethods: ['get','post'] } }) |
| 单次覆盖 baseURL | request.get('/x', { meta: { baseURL: 'https://alt.example.com' } }) |
| 跳过鉴权(不触发 401 刷新) | request.get('/public', { meta: { skipAuth: true } }) |
| 错误对象(规范化) | catch (e) { /* e = { code, message, ... } */ } |
| 可能的错误码 | network / not_found / server / unauthorized / fallback |
| 手动刷新(可选) | const ok = await refreshOnce() // true|null|throw |
🧱 示例测试项目
仓库内提供了一个最小化的测试项目,便于在真实工程外快速验证网络请求封装行为:
cd examples/test-project
npm install
npm run build
npm start❗ 注意事项
- **前端不存任何 token**;凭证由 **HttpOnly Cookie** 维护,浏览器自动携带。
- **不注入 Authorization 头**;所有鉴权靠 Cookie + 服务端校验。
- 默认 **401 自动刷新 1 次**(成功后重放原请求),**网络/5xx 自动重试 3 次**(幂等方法,指数退避)。
- CORS:后端需配置 `Access-Control-Allow-Origin` 为前端真实域名(不能 `*`)、`Access-Control-Allow-Credentials: true`,并放行 `X-CSRF-Token` 头;同时加 `Vary: Origin`。
- Cookie 建议:`HttpOnly; Secure; Path=/`(AT),`Path=/auth`(RT),同子域共享请设置 `Domain=.example.com`;跨站场景 `SameSite=None`(尽量避免第三方 Cookie)。
- 退出登录由**后端**通过 `Set-Cookie`(参数完全匹配、`Max-Age=0`)成对清理 AT/RT;前端只做路由与 UI 清理。
- 本库仅封装通信与状态,不包含业务 API;基于 Axios v1+,ESM 导出。
🚀 发布与版本管理
发布前检查
git status
npm whoami --registry=https://npm.pkg.github.com发布流程
# 1) 依赖&构建&测试
npm ci
npm run build
# 2) 打包清单自检(不生成文件,仅列出将被包含的内容)
npm pack --dry-run
# 3) 试发布(不上传),验证元数据/脚本/访问级别
npm publish --dry-run --registry=https://npm.pkg.github.com
# 4) 确认版本号,再更新
npm version patch
# 5) 正式发布
npm publish --registry=https://npm.pkg.github.com© Greentourasia Frontend Engineering Team 适用于公司内部所有 Web / Admin 前端项目。
