Skip to content

中间件目录

orva 已经有比较完整的中间件层,但前提是这些能力得“找得到、看得懂、拿来就能用”。这页就是当前主线版本的完整目录:每个中间件都包含用途说明、子模块导入路径和最小示例。

如果你更想先拿到“按场景配好的组合”,而不是完整目录,先看 Middleware Cookbook

导入方式

应用项目里,优先用聚合导入:

ts
import { cors, requestId, secureHeaders } from 'orvajs/middlewares';

库、模板、脚手架、共享基建里,优先用细粒度子路径:

ts
import { cors } from 'orvajs/middlewares/cors';
import { requestId } from 'orvajs/middlewares/request-id';
import { secureHeaders } from 'orvajs/middlewares/secure-headers';

快速选择

场景推荐组合
浏览器 APIrequestId() logger() cors() secureHeaders() bodyLimit() responseTime()
内部后台basicAuth() requireOrigin() rateLimit() secureHeaders()
对外接口bearerAuth()apiKeyAuth() 再配 rateLimit() requestId() responseTime()
静态资源serveStatic() 配合 etag() compress() cacheControl()
安全基线secureHeaders() 再加 contentSecurityPolicy()strictTransportSecurity()

如何看示例

示例都故意保持最小配置,方便你直接复制。更大的项目建议把这些栈收敛进路由组或共享中间件工厂。

Authentication

这一组负责鉴权,并会把认证结果写入下游 Context 变量。

中间件导入路径适用场景最小示例
basicAuth()orvajs/middlewares/basic-auth浏览器登录弹窗、内部控制台、简易后台app.use(basicAuth({ users: { admin: 'secret' } }))
bearerAuth()orvajs/middlewares/bearer-authBearer Token API、服务间调用app.use(bearerAuth({ token: ['token-a', 'token-b'] }))
apiKeyAuth()orvajs/middlewares/api-key-authHeader / Query 形式的 API Keyapp.use(apiKeyAuth({ key: ['k1'], headerName: 'X-API-Key' }))

认证组合示例

ts
import { createOrva } from 'orvajs';
import { apiKeyAuth, basicAuth, bearerAuth } from 'orvajs/middlewares';

const app = createOrva()
  .get('/admin', basicAuth({ users: { admin: 'secret' } }), (c) => c.text('ok'))
  .get('/internal', bearerAuth({ token: 'internal-token' }), (c) => c.text('ok'))
  .get('/partners', apiKeyAuth({ key: ['partner-key'], queryName: 'apiKey' }), (c) => c.text('ok'));

Guards

这组中间件适合在业务 handler 之前就把不合格请求挡掉。

中间件导入路径适用场景最小示例
allowMethods()orvajs/middlewares/allow-methods只允许少数方法通过app.use(allowMethods(['GET', 'POST']))
blockMethods()orvajs/middlewares/block-methods禁止危险或不支持的方法app.use(blockMethods(['TRACE', 'CONNECT']))
requireHeader()orvajs/middlewares/require-header强制要求请求头存在app.use(requireHeader(['x-tenant-id']))
requireQuery()orvajs/middlewares/require-query强制要求 query 参数存在app.use(requireQuery(['page']))
requireJson()orvajs/middlewares/require-json写请求必须是 application/jsonapp.use(requireJson())
requireAccept()orvajs/middlewares/require-accept强制 Accept 协商app.use(requireAccept(['application/json']))
bodyLimit()orvajs/middlewares/body-limit拒绝超大请求体app.use(bodyLimit({ maxBytes: 1024 * 1024 }))
timeout()orvajs/middlewares/timeout超时后直接返回失败响应app.use(timeout({ ms: 5_000 }))
rateLimit()orvajs/middlewares/rate-limit抗突发流量和滥用app.use(rateLimit({ limit: 100, windowMs: 60_000 }))
hostAllowlist()orvajs/middlewares/host-allowlist限制有效 Hostapp.use(hostAllowlist(['api.example.com']))
blockUserAgents()orvajs/middlewares/block-user-agents屏蔽爬虫或异常客户端app.use(blockUserAgents([/curl/i, 'BadBot']))
requireOrigin()orvajs/middlewares/require-origin限制浏览器来源app.use(requireOrigin(['https://app.example.com']))
idempotencyKey()orvajs/middlewares/idempotency-key写接口强制 Idempotency-Keyapp.use(idempotencyKey())
csrfOrigin()orvajs/middlewares/csrf-origin带 body 请求做 CSRF Origin 校验app.use(csrfOrigin(['https://app.example.com']))

守卫组合示例

ts
import { createOrva } from 'orvajs';
import {
  allowMethods,
  bodyLimit,
  idempotencyKey,
  rateLimit,
  requireJson,
  requireOrigin,
} from 'orvajs/middlewares';

const app = createOrva().use(
  allowMethods(['GET', 'POST', 'PATCH']),
  requireOrigin(['https://app.example.com']),
  requireJson(),
  bodyLimit({ maxBytes: 2 * 1024 * 1024 }),
  idempotencyKey(),
  rateLimit({ limit: 60, windowMs: 60_000 }),
);

HTTP Response

这组负责响应头、重定向、缓存校验器和响应元数据修饰。

中间件导入路径适用场景最小示例
poweredBy()orvajs/middlewares/powered-by添加 X-Powered-Byapp.use(poweredBy('orva'))
responseHeaders()orvajs/middlewares/response-headers追加静态或动态响应头app.use(responseHeaders({ headers: { 'x-app': 'orva' } }))
cacheControl()orvajs/middlewares/cache-control设置缓存策略app.use(cacheControl('public, max-age=60'))
noStore()orvajs/middlewares/no-store禁止缓存app.use(noStore())
vary()orvajs/middlewares/varyVaryapp.use(vary('Origin', 'Accept-Encoding'))
cors()orvajs/middlewares/cors浏览器跨域访问app.use(cors({ origin: ['https://app.example.com'], credentials: true }))
httpsRedirect()orvajs/middlewares/https-redirectHTTP 跳转 HTTPSapp.use(httpsRedirect({ status: 308 }))
trailingSlash()orvajs/middlewares/trailing-slash统一尾斜杠策略app.use(trailingSlash({ mode: 'remove' }))
etag()orvajs/middlewares/etag添加强 ETag 和 304app.use(etag())
responseTag()orvajs/middlewares/response-tag打一个单独响应头标记app.use(responseTag('x-release', '2026-04'))
contentType()orvajs/middlewares/content-type提供默认内容类型app.use(contentType('application/json; charset=utf-8'))
checksum()orvajs/middlewares/checksum给响应体加摘要头app.use(checksum('X-Body-SHA1'))
responseChecksumTrailer()orvajs/middlewares/response-checksum-trailer输出 Digest 风格摘要app.use(responseChecksumTrailer('Digest'))
contentLength()orvajs/middlewares/content-length缺失时补 Content-Lengthapp.use(contentLength())

HTTP 组合示例

ts
import { createOrva } from 'orvajs';
import {
  cacheControl,
  cors,
  etag,
  responseHeaders,
  secureHeaders,
  vary,
} from 'orvajs/middlewares';

const app = createOrva().use(
  cors({ origin: ['https://app.example.com'], credentials: true }),
  secureHeaders(),
  cacheControl('public, max-age=60'),
  vary('Origin', 'Accept-Encoding'),
  responseHeaders({ headers: { 'x-service': 'edge-api' } }),
  etag(),
);

Observability

这组负责记录请求信息,并写入响应头或 c.var

中间件导入路径适用场景最小示例
logger()orvajs/middlewares/logger控制台或自定义请求日志app.use(logger({ includeQuery: true }))
requestId()orvajs/middlewares/request-id请求关联 IDapp.use(requestId({ contextKey: 'requestId' }))
responseTime()orvajs/middlewares/response-time响应耗时头app.use(responseTime())
requestMeta()orvajs/middlewares/request-meta把 method/path/query/headers 写入上下文app.use(requestMeta())
userAgent()orvajs/middlewares/user-agentUser-Agent 写入上下文app.use(userAgent())
clientIp()orvajs/middlewares/client-ip从代理头提取 IPapp.use(clientIp())
serverTiming()orvajs/middlewares/server-timing输出 Server-Timingapp.use(serverTiming('app;dur=12'))
requestContext()orvajs/middlewares/request-context聚合 IP / UA / Origin 信息app.use(requestContext())
requestSize()orvajs/middlewares/request-size记录请求大小app.use(requestSize())
locale()orvajs/middlewares/locale解析 Accept-Languageapp.use(locale('zh-CN'))
requestBodyText()orvajs/middlewares/request-body-text保存原始 body 文本app.use(requestBodyText())

观测组合示例

ts
import { createOrva } from 'orvajs';
import {
  clientIp,
  logger,
  requestContext,
  requestId,
  responseTime,
  serverTiming,
} from 'orvajs/middlewares';

const app = createOrva().use(
  requestId(),
  clientIp(),
  requestContext(),
  logger({ includeQuery: true }),
  responseTime(),
  serverTiming('app;dur=8'),
);

Security Headers

如果你只是要一套安全默认值,先上 secureHeaders();如果要企业级定制,再拆成单项策略。

中间件导入路径适用场景最小示例
contentSecurityPolicy()orvajs/middlewares/content-security-policyCSP 与 report-only 策略app.use(contentSecurityPolicy({ directives: { defaultSrc: [\"'self'\"] } }))
referrerPolicy()orvajs/middlewares/referrer-policy控制 Referrer 泄露app.use(referrerPolicy('strict-origin-when-cross-origin'))
frameOptions()orvajs/middlewares/frame-options防止点击劫持app.use(frameOptions('DENY'))
xContentTypeOptions()orvajs/middlewares/x-content-type-options禁止 MIME sniffingapp.use(xContentTypeOptions())
xDnsPrefetchControl()orvajs/middlewares/x-dns-prefetch-control控制 DNS 预取app.use(xDnsPrefetchControl(false))
xDownloadOptions()orvajs/middlewares/x-download-optionsIE 下载安全头app.use(xDownloadOptions())
xPermittedCrossDomainPolicies()orvajs/middlewares/x-permitted-cross-domain-policies限制 Adobe/Flash 跨域策略app.use(xPermittedCrossDomainPolicies('none'))
xXssProtection()orvajs/middlewares/x-xss-protection兼容旧浏览器 XSS 头app.use(xXssProtection('0'))
strictTransportSecurity()orvajs/middlewares/strict-transport-securityHSTSapp.use(strictTransportSecurity({ maxAge: 31536000, preload: true }))
permissionsPolicy()orvajs/middlewares/permissions-policy限制浏览器能力app.use(permissionsPolicy({ directives: { geolocation: [] } }))
crossOriginEmbedderPolicy()orvajs/middlewares/cross-origin-embedder-policyCOEPapp.use(crossOriginEmbedderPolicy('require-corp'))
crossOriginOpenerPolicy()orvajs/middlewares/cross-origin-opener-policyCOOPapp.use(crossOriginOpenerPolicy('same-origin'))
crossOriginResourcePolicy()orvajs/middlewares/cross-origin-resource-policyCORPapp.use(crossOriginResourcePolicy('same-origin'))
originAgentCluster()orvajs/middlewares/origin-agent-clusterOrigin-Agent-Cluster 隔离app.use(originAgentCluster('?1'))
secureHeaders()orvajs/middlewares/secure-headers一组合理的安全默认头app.use(secureHeaders())

安全头组合示例

ts
import { createOrva } from 'orvajs';
import {
  contentSecurityPolicy,
  secureHeaders,
  strictTransportSecurity,
} from 'orvajs/middlewares';

const app = createOrva().use(
  secureHeaders(),
  contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      imgSrc: ["'self'", 'data:'],
      scriptSrc: ["'self'"],
    },
  }),
  strictTransportSecurity({
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true,
  }),
);

Asset Delivery

这组通常会在文档站、控制台或上传文件入口里最先用到。

中间件导入路径适用场景最小示例
serveStatic()orvajs/middlewares/serve-static静态文件、manifest、SPA fallbackapp.get('/assets/*', serveStatic({ root: 'public', prefix: '/assets', etag: true }))
compress()orvajs/middlewares/compressBrotli / gzip / deflate 压缩app.use(compress({ threshold: 1024, encodings: ['br', 'gzip'] }))

静态资源组合示例

ts
import { createOrva } from 'orvajs';
import { cacheControl, compress, etag, serveStatic } from 'orvajs/middlewares';

const app = createOrva()
  .use(compress({ threshold: 1024, encodings: ['br', 'gzip'] }), cacheControl('public, max-age=600'), etag())
  .get('/assets/*', serveStatic({
    root: 'public',
    prefix: '/assets',
    index: false,
    etag: true,
  }))
  .get('/*', serveStatic({
    root: 'public',
    spaFallback: 'index.html',
  }));

这一组不是 app.use() 中间件,而是底层工具函数,适合给自定义中间件、适配器、认证流程和测试使用。

工具导入路径适用场景最小示例
getCookie()orvajs/middlewares/cookie从请求里读单个 cookieconst session = getCookie(request, 'session')
parseCookieHeader()orvajs/middlewares/cookie解析整条 cookie headerconst cookies = parseCookieHeader(request.headers.get('cookie'))
serializeCookie()orvajs/middlewares/cookie生成 Set-CookieserializeCookie('theme', 'dark', { path: '/', httpOnly: true })
serializeDeleteCookie()orvajs/middlewares/cookie生成删除 cookie 的 header 值serializeDeleteCookie('session', { path: '/' })
ts
import { defineMiddleware } from 'orvajs';
import { getCookie, serializeCookie, serializeDeleteCookie } from 'orvajs/middlewares/cookie';

export const sessionCookies = defineMiddleware(async (c, next) => {
  const session = getCookie(c.req, 'session');

  c.after((response) => {
    if (!session) {
      response.headers.append('Set-Cookie', serializeCookie('session', 'new-session', {
        path: '/',
        httpOnly: true,
      }));
    }
    return response;
  });

  await next();
});

export function logoutHeaders(): Headers {
  return new Headers({
    'Set-Cookie': serializeDeleteCookie('session', { path: '/' }),
  });
}

新项目先上什么

如果你只是想先拿到一套稳妥的默认栈,最短路径仍然是:

ts
import { createOrva } from 'orvajs';
import {
  bodyLimit,
  cors,
  logger,
  requestId,
  responseTime,
  secureHeaders,
} from 'orvajs/middlewares';

const app = createOrva().use(
  requestId(),
  logger(),
  cors(),
  secureHeaders(),
  bodyLimit({ maxBytes: 1024 * 1024 }),
  responseTime(),
);

先跑起来,再按真实路由需求继续叠加。

Built with VitePress. Structured for production docs, multilingual delivery and long-term versioning.