用 Makers 搭建多项目平台时,只需接入一个泛域名,即可把子域名分配给各个独立项目,Makers 会自动将请求路由到对应项目,无需自行维护这层分发逻辑。平台请求中间件绑定在泛域名上,在请求进入项目前执行,一份脚本即可为该域名下的所有项目统一处理鉴权、流量控制等公共逻辑,无需在每个项目中重复开发。


如何配置
中间件按泛域名生效,以单个
.js 文件上传。配置步骤:1. 联系我们 为平台接入泛域名(例如
*.example.com),并确认泛域名已生效。2. 在控制台进入 设置 > 平台与多租户,在目标泛域名的请求中间件一列上传脚本。


上传后约 15 分钟生效,生效后该域名下所有项目的请求都会先经过它。同一泛域名只保留一份中间件,再次上传即替换当前版本;在同一入口也可更新、下载或删除已有脚本。
脚本结构
文件里只能有一个顶层声明,且必须是下面这个函数。参数名必须是
context。async function onRequest(context) {}
此外:
不能写
import、export,也不能使用动态 import()。不能在顶层再声明变量、函数或其他语句。需要复用的函数写在
onRequest 内部。不能引入外部依赖,也不能使用 Node.js 接口,例如
require、fs、process。脚本按 ES2023 编译后执行。可以使用
Request、Response、URL、Headers 这些 Web 接口。配置约束
只能为已经生效的泛域名配置,配置后约 15 分钟生效。
每个泛域名只有一份请求中间件,再次上传会替换当前版本。
同一泛域名的上传或更新至少间隔 30 秒。
只接受
.js 文件,编码必须是 UTF-8,文件不超过 1 MB。context 参数
onRequest 收到的 context 有以下成员:成员 | 说明 |
request | 当前进入中间件的请求,可以读取 URL、方法、请求头和请求体。 |
fetch(input, init?) | 获取当前项目的响应, input 传 Request 或 URL 字符串,init为可选参数,含义与 RequestInit 相同。 |
waitUntil(promise) | 注册一个 Promise,响应返回之后,运行时仍会等待它结束,它不改变已经返回的响应。 |
async function onRequest(context) {const request = context.request;// 获取完整的请求对象const url = new URL(request.url);// 构造 URL 对象const response = await context.fetch(request);// 对请求进行获取,暂不返回const copy = response.clone();// 复制请求,测试异步等待context.waitUntil(copy.arrayBuffer());// 等待异步完成return response;}
示例
接口访问控制
/api/ 以外的请求原样交给项目,/api/ 必须带约定的 Authorization,否则返回 401,不再进入项目。async function onRequest(context) {const request = context.request;const url = new URL(request.url);const platformToken = 'xxx';//平台 Tokenif (!url.pathname.startsWith("/api/")) {return context.fetch(request);}const token = request.headers.get("authorization");if(token != platformToken){return new Response(JSON.stringify({ code: 401, message: "unauthorized" }), {status: 401,headers: { "content-type": "application/json; charset=utf-8" },});}return context.fetch(request);}
统一增加响应头
取回项目响应后,统一增加响应头并返回。
async function onRequest(context) {const response = await context.fetch(context.request);const headers = new Headers(response.headers);headers.set("x-middleware", "1");return new Response(response.body, {status: response.status,statusText: response.statusText,headers,});}