@xiao-ying/miniapp-proxy
v1.3.0
Published
Standalone dev proxy server and Vite plugin for XiaoYing miniapp SDK
Maintainers
Readme
@xiao-ying/miniapp-proxy
独立的动态代理服务与 Vite 插件,可在开发时把浏览器请求转发到任意 http/https 或 ws/wss 目标。
开发态跨域与 dynamicProxyPlugin(快速使用)
- 安装(仅 dev):
pnpm add -D @xiao-ying/miniapp-proxy- 在
vite.config.ts启用(建议用loadEnv传入 token 等):
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
import { dynamicProxyPlugin } from '@xiao-ying/miniapp-proxy'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), 'VITE_')
const proxyPrefix = env.VITE_XY_PROXY_PREFIX ?? '/dev-proxy/'
const allowTarget = (url: URL) => url.hostname.endsWith('.example.com')
return {
plugins: [
react(),
dynamicProxyPlugin({
prefix: proxyPrefix, // 默认 /dev-proxy
token: env.VITE_XIAOYING_TOKEN,
tokenTargets: env.VITE_XIAOYING_TOKEN_TARGETS,
allowTarget, // 可选:拒绝不允许的目标
secure: false // 允许自签名证书
})
]
}
})- 运行时开启代理(浏览器分支会自动重写请求 URL):
const prefix = import.meta.env.VITE_XY_PROXY_PREFIX ?? '/dev-proxy/'
window.__XY_CONFIG__ = {
runtime: 'browser',
devProxy: { enable: true, prefix }
}- 发起请求:
const target = 'https://api.example.com'
const proxyUrl = `${prefix}${encodeURIComponent(new URL(target).origin)}/${encodeURIComponent('/v1/foo')}`
fetch(proxyUrl, { method: 'GET' })WebSocket 代理
同样使用 /dev-proxy/<encodedTargetOrigin>/<encodedTargetPathAndSearch> 形式即可:
const prefix = import.meta.env.VITE_XY_PROXY_PREFIX ?? '/dev-proxy/'
const wsTarget = 'wss://ws.example.com/socket'
const wsTargetUrl = new URL(wsTarget)
const ws = new WebSocket(
`${prefix}${encodeURIComponent(wsTargetUrl.origin)}/${encodeURIComponent(
wsTargetUrl.pathname + wsTargetUrl.search
)}`
)说明:
- WS 仅允许
ws:///wss://目标,HTTP 仍仅允许http:///https://。 - 代理会移除
Origin/Referer/Host头,避免跨域检查干扰。
独立进程用法
import { startProxy } from '@xiao-ying/miniapp-proxy'
startProxy({
port: 9000,
prefix: '/dev-proxy'
})作为中间件使用
需要自行接入到任意 Node HTTP 框架时,可直接使用 createProxyMiddleware:
import express from 'express'
import { createProxyMiddleware } from '@xiao-ying/miniapp-proxy'
const app = express()
app.use(createProxyMiddleware({ prefix: '/dev-proxy' }))请求体预览(bodyPreview)
bodyPreview 现为显式开启的调试能力,默认关闭。开启后会在日志打印请求体前 N 字节(默认 2048),便于快速核对参数:
dynamicProxyPlugin({
bodyPreview: { enabled: true, maxBytes: 4096 },
})预览仅在有请求体的场景(非 GET/HEAD/OPTIONS)生效。它主要用于排查开发态请求参数问题,后续可能根据团队反馈进一步精简或移除。
Cookie 域与路径改写(cookieRewrite)
已默认开启 Cookie 改写,用于开发态访问统一认证/SSO 后端时避免 Domain/Path 不匹配导致会话丢失:
- 移除响应
Set-Cookie的Domain=...(改为代理域 host-only cookie)。 - 将
Path=...强制改写为按目标隔离的作用域路径:/dev-proxy/<encodeURIComponent(targetOrigin)>。 - 若原 Cookie 没有
Path,会自动补上同样的作用域路径。 - 实际代理 URL 使用分段编码:
/dev-proxy/<encodedTargetOrigin>/<encodedTargetPathAndSearch>,这样浏览器后续请求才能正确命中前面改写过的 Cookie Path。 - 其他属性(
HttpOnly/Secure/SameSite/Expires/Max-Age)保持不变。
关闭改写(兼容特殊后端):
dynamicProxyPlugin({
cookieRewrite: false
})开发者凭证注入
如需在调试时自动为指定目标追加 XIAOYING-TOKEN 请求头,推荐在 vite.config.ts 里用 loadEnv 读取并通过插件参数传入(见上例)。同时仍兼容直接使用环境变量:
VITE_XIAOYING_TOKEN(优先)/XIAOYING_TOKEN(回退):要注入的 token(为空则不注入)。VITE_XIAOYING_TOKEN_TARGETS(优先)/XIAOYING_TOKEN_TARGETS(回退):逗号分隔的 host/port 通配符,默认值为xiaoying.life,*.xiaoying.life,*.xiaoying.xyz:44。示例:VITE_XIAOYING_TOKEN_TARGETS="*.internal.example.com:8080,api.example.com"
仅当目标 URL 匹配这些规则时才会附加 XIAOYING-TOKEN,其余目标保持原样转发。
约定与可选项
prefix: 代理前缀,带/不带尾斜杠皆可,默认/dev-proxy。allowTarget(url: URL): 可选白名单钩子,返回false则拒绝转发。secure: 是否验证上游 HTTPS 证书,默认false(允许自签名)。bodyPreview:boolean | { enabled?: boolean; maxBytes?: number },日志打印请求体前若干字节,默认关闭;仅在有请求体时生效,主要用于显式开启的调试场景。cookieRewrite:boolean | { enabled?: boolean },默认开启。开启后会移除Set-Cookie的Domain,并将Path改为按目标隔离的路径作用域;可传false关闭。- HTTP 仅转发 http/https;WS 仅转发 ws/wss,其他协议会被拒绝。
- 默认
changeOrigin: true,secure: false(允许自签名证书)。 - 可以通过
allowTarget添加额外白名单校验;通过log接管日志输出。 proxyOptions可透传给http-proxy-middleware,满足高级定制需求。
其他形态
- 需要独立进程时,可用同包的
startProxy启动本地服务,再由 Viteserver.proxy转发。 - 不希望在 Vite 中内置开放代理时,可改用 Nginx/公司网关等方案,但需显式验证白名单以避免滥用。
