@seaart/request-seaart
v0.1.3
Published
SeaArt request protocol strategy for @seaart/request
Readme
@seaart/request-seaart
SeaArt Web 的请求协议策略包,构建在 @seaart/request 之上。它将 SeaArt 标准请求头、语言、灰度、SSR 上下文、Cookie 白名单和 Token 刷新抽成框架无关策略;不依赖 Nuxt、Vue、Pinia、路由或 UI 组件。
调用方负责从自身框架读取 Cookie、运行时 API 地址和状态,并通过 getContext 注入。本包不会主动读写浏览器存储,也不会执行登录跳转或展示错误提示。
安装
pnpm add @seaart/request-seaart axios@seaart/request-seaart 会自动安装 @seaart/request;axios 是请求内核的 peer dependency,需由接入项目提供。
使用
import { createSeaartRequestClient } from '@seaart/request-seaart';
export const request = createSeaartRequestClient({
getContext: () => ({
isServer: false,
baseURL: 'https://api.example.com',
locale: getCurrentLocale(),
token: getAccessToken(),
deviceId: getDeviceId(),
appId: 'web_global_seaart',
}),
onTokenRefresh: (token) => saveAccessToken(token),
onBusinessError: (error) => reportBusinessError(error.status),
onHttpError: (error) => reportHttpError(error),
});
const result = await request({
url: '/api/v1/artwork/list',
method: 'POST',
data: { page: 1 },
});客户端参数
createSeaartRequestClient(options) 支持 @seaart/request 的 axiosInstance、timeout、withCredentials、headers、successCodes、isSuccess、onHttpError 等内核参数,并增加以下 SeaArt 协议配置:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| getContext | (config) => SeaartRequestContext | 是 | - | 每个请求获取上下文;支持异步,同一请求只读取一次。 |
| platform | string | 否 | 'web' | 注入 X-Platform 的默认值,例如 H5 可传 'h5'。 |
| projectId | string | 否 | 'seaart' | 注入 X-Project-Id 的默认值。 |
| createRequestId | () => string | 否 | crypto.randomUUID() | 生成 X-Request-Id。 |
| resolveGrayType | (url, abInfo) => string | 否 | - | 根据请求 URL 和 AB 信息生成 X-Gray-Type。 |
| onTokenRefresh | (token, response) => void | 否 | - | 成功响应带有 token Header 时调用。 |
| onResponse | (response, data) => void | 否 | - | 收到响应后的扩展钩子。 |
| onBusinessError | (error, response) => void | 否 | - | SeaArt 业务码失败时调用;不负责 UI 或跳转。 |
| cookieWhitelist | string[] | 否 | 内置白名单 | 覆盖 SSR Cookie 白名单,而非追加。 |
请求上下文
getContext 返回以下字段;无值字段不会生成请求头。
| 字段 | 类型 | 生成的配置或请求头 | 说明 |
| --- | --- | --- | --- |
| isServer | boolean | - | 标记 SSR 请求;仅 SSR 执行 Cookie、IP、UA 透传。 |
| baseURL | string | config.baseURL | 请求未显式指定 baseURL 时使用。 |
| withCredentials | boolean | config.withCredentials | 覆盖本次请求的凭据模式。 |
| locale | string | Accept-Language | 多语言标准字段。 |
| language | string | Accept-Language | 已弃用兼容字段;locale 优先。 |
| token | string | Token | 认证 Token。 |
| deviceId | string | X-Device-Id | 设备标识。 |
| grayTag | string | X-Gray-Tag | 灰度标签。 |
| browserId | string | X-Browser-Id | 浏览器标识。 |
| canary | boolean | X-Canary: true | Canary 开关。 |
| pageId | string | X-Page-Id | 页面标识。 |
| xEyes | string | X-Eyes | 实验/风控上下文。 |
| appId | string | X-App-Id | 应用标识。 |
| adId | string | X-Ad-Id | 广告归因标识。 |
| grayRelease | boolean | X-Gray-Release: true | 预发布灰度标识。 |
| abInfo | unknown | - | 仅传给 resolveGrayType。 |
| incomingHeaders | Headers \| Record<string, string \| string[]> | SSR 转发头 | SSR 原始入站头。 |
| cookie | string | cookie | SSR 原始 Cookie;未传时从 incomingHeaders.cookie 读取。 |
每个请求默认注入 X-Request-Id、X-Platform: web 与 X-Project-Id: seaart;可通过客户端参数 platform 和 projectId 覆盖后两个值。
SSE 流式请求
createSeaartSseClient 使用 fetch 读取 text/event-stream,可用于需要 POST 请求体和 SeaArt 鉴权 Header 的流式接口。它与普通请求共用 getContext、语言、Token、灰度和 SSR Cookie 白名单规则,但不走 Axios,也不执行 JSON 业务码判断。
import { createSeaartSseClient } from '@seaart/request-seaart';
const sse = createSeaartSseClient({
getContext: () => ({
baseURL: 'https://api.example.com',
locale: getCurrentLocale(),
token: getAccessToken(),
}),
onTokenRefresh: (token) => saveAccessToken(token),
});
const stream = sse({
url: '/api/v1/chat/stream',
method: 'POST',
data: { prompt: 'Describe this image' },
parseJson: true,
onMessage({ event, data }) {
if (event === 'chunk') appendMessage(data);
},
onError(error) {
reportStreamError(error);
},
});
await stream.done;
stream.abort();| 参数 | 说明 |
| --- | --- |
| url | 必填。相对路径会结合 getContext().baseURL 请求。 |
| method / data / params / headers | 请求方法、请求体、Query 和单次附加 Header。默认方法为 GET。 |
| timeout | 仅限制连接并收到响应头的时间;已开始的流不会因该参数被中断。 |
| parseJson | 为 true 时,尝试将每个 SSE data 字段解析为 JSON;解析失败仍返回原始字符串。 |
| onChunk | 每次收到原始文本分块时调用。适合歌词、图片反推等调用方自行按行或业务终止符解析的流。 |
| onReader | 完全接管 ReadableStream reader;传入后包不再解析 SSE 帧,兼容旧 customReader / onReader 模式。 |
| onOpen / onMessage / onComplete / onError | 分别处理握手成功、标准 SSE 事件、流结束和异常。 |
| signal / stream.abort() | 取消流;主动取消会使 done 正常完成,并收到 onComplete({ aborted: true })。 |
| reconnect | 默认关闭。显式传入 { maxRetries, delay, lastEventId, onRetry } 后,仅在连接异常时重试;lastEventId: true 会带上最近收到事件的 Last-Event-ID。POST 接口必须由调用方确认幂等后再开启。 |
事件回调参数包含 event(默认 message)、data、rawData、可选 id 和 retry。包支持标准 SSE 的多行 data:,但不解释 chunk、end、[DONE]、---end--- 等业务事件。
SSR 安全策略
SSR 不会透传全部 Cookie 和入站 Header。默认仅保留下列 Cookie:
T, browserId, app_id, enable_character, enable_ai_video, enable_ai_audio,
isCache, x_canary, lang, deviceId, grayTag, publish_popover_last_date仅转发 X-Forwarded-For 和 User-Agent。这可避免将无关或超长 Cookie 发送到后端网关,也避免无意传播 Referer 等隐私字段。
const request = createSeaartRequestClient({
getContext: () => ({
isServer: true,
baseURL: process.env.API_BASE_URL,
locale: 'zhCN',
incomingHeaders: requestHeaders,
cookie: requestHeaders.cookie,
}),
});可导入 filterSsrRequestCookies 与 getSsrForwardedHeaders,在接入层进行独立测试或调试。
响应与错误
本包沿用内核的默认业务成功码:10000、10404、500401。HTTP 响应 Header 包含 token 时,会先调用 onTokenRefresh,再执行 onResponse;业务错误随后 reject ApiBusinessError。
登录失效跳转、Pinia 更新、Toast、埋点和具体错误码交互都应在 onTokenRefresh、onBusinessError 或业务项目的响应钩子中完成。
适用边界
- 普通 SeaArt JSON HTTP 接口:使用本包。
- SSE/流式响应:使用专用流式请求实现。
- CDN 与预签名 PUT:使用原生
fetch,不注入业务鉴权头。 - 媒体上传的
pre-sign、complete等业务接口:由业务项目将本包实例注入@seaart/edge-media-upload的request依赖。
测试与构建
pnpm --filter @seaart/request-seaart typecheck
pnpm --filter @seaart/request-seaart test
pnpm --filter @seaart/request-seaart buildLicense
UNLICENSED
