资讯动态

Puter Worker 路由 handler 怎么接收 request、user、params 并返回不同响应类型?

发布时间:2026/9/10 7:38:16 来源:尧图企业网站定制
Puter Worker 路由 handler 怎么接收 request、user、params 并返回不同响应类型【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter用 Puter Worker 写服务端 API 时运行时会在你的代码里自动注入一个router对象你用router.get/post/put/delete/options注册路由每个 handler 只接收一个可解构的参数对象——标题里的request、user、params都从它来而 handler 的返回值决定客户端拿到什么样的响应。本文基于 router 文档 及其关联文档走一遍「定义 handler → 部署 worker → 逐项验证请求参数与响应类型」的完整路径。准备条件一个已验证邮箱的 Puter 账号这是创建 worker 的前提见 create 文档。worker 的 JavaScript 文件不能大于 10MBworker 名称只能包含字母、数字、连字符和下划线。worker 创建或更新后完全生效需要 530 秒传播到所有边缘服务器测试前需要等一段时间。handler 的三个参数从哪来路由 handler 接收一个对象参数文档定义的可解构属性有三个属性含义request传入的 HTTP 请求标准Request对象user发起本次请求的用户对象带puter属性user.puter仅在 worker 通过puter.workers.exec()被调用时可用params从路由路径中捕获的路由参数request读 body、query 和 headersrequest就是标准Request对象读 JSON body、表单数据、query 字符串、headers 都走它自己的方法// JSON body router.post(/api/user, async ({ request }) { const body await request.json(); return { processed: true }; }); // 表单数据 router.post(/api/user, async ({ request }) { const formData await request.formData(); return { processed: true }; }); // query 字符串 router.get(/api/search, async ({ request }) { const url new URL(request.url); const query url.searchParams.get(q); return { query }; }); // headers router.post(/api/user, async ({ request }) { const contentType request.headers.get(content-type); return { processed: true }; });以上四段均取自 router 文档的 Examples 部分可原样照抄。注意 query 参数不在params里而是从request.url解析。params:name与*name两种捕获方式路径中不固定的片段用冒号前缀捕获每个捕获到的片段按你起的名字成为params上的属性router.get(/api/posts/:category/:id, async ({ params }) { const { category, id } params; return { category, id }; });按文档说明请求/api/posts/tech/42匹配该路由后得到params.category→tech、params.id→42。捕获值永远是字符串如果预期是数字要自己转换。*name通配符匹配路径剩余部分任意多个片段匹配值同样挂在params上router.get(/files/*path, async ({ params }) { // 请求 /files/images/avatars/me.png 时 // params.path images/avatars/me.png return { path: params.path }; });通配符必须命名写*path而不是裸*。/files/*里没名字的*会被当作字面字符路由只能精确匹配/files/*这个路径。通配符的常见用途是兜底 404 路由——把它定义在最后只让其他路由都没匹配上时执行。user与me两个 Puter 上下文worker 代码里还有全局对象me代表 worker 的拥有者你。两个上下文的分工文档写得很明确me.puter是 worker 上下文操作你的 KV、FS、AI 等资源计到你名下user.puter是调用者上下文只有当 worker 通过puter.workers.exec()执行时才存在——exec()会把用户的 Puter token 放在自定义puter-auth请求头里发过来user.puter就是靠它填充的。同一个 worker 里可以混用有的端点读写自己的数据me.puter有的端点操作调用用户的数据user.puter操作计到实际调用的那个上下文名下这是 Puter 的 User-Pays 模型。handler 能返回哪些响应类型handler 的返回值被运行时分发成不同响应文档列出的形式如下返回什么得到什么响应JS 对象如{ status: ok }自动转换成 JSON 响应字符串纯文本响应BlobBlob 响应可指定 MIME 类型Uint8Array二进制响应ReadableStream二进制流式响应Response自己控制 status code 和 headers对应写法均出自 router 文档 Examples// JSON对象自动转换 router.get(/api/simple, async ({ request }) { return { status: ok }; }); // 纯文本 router.get(/api/text, async ({ request }) { return Hello World; }); // Blob router.get(/api/blob, async ({ request }) { return new Blob([Hello World], { type: text/plain }); }); // Uint8Array router.get(/api/uint8array, async ({ request }) { return new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); }); // ReadableStream router.get(/api/binary-stream, async ({ request }) { return new ReadableStream({ start(controller) { controller.enqueue( new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]) ); controller.close(); }, }); }); // 自定义 status 和 headers router.get(/api/custom, async ({ request }) { return new Response(JSON.stringify({ data: custom }), { status: 200, headers: { Content-Type: application/json, Custom-Header: value, }, }); });要返回 400/401/404/500 这类错误状态码同样得自己构造Response并设置status。文档给出的错误处理模式router.post(/api/risky-operation, async ({ request }) { try { const body await request.json(); const result await someRiskyOperation(body); return { success: true, result }; } catch (error) { return new Response( JSON.stringify({ error: Operation failed, message: error.message, }), { status: 500, headers: { Content-Type: application/json }, } ); } });其中someRiskyOperation(body)是文档示例里的占位调用使用时替换成你自己可能失败的业务逻辑。写一个可验证的 worker把上面各形态各取一个端点组装成一个文件每个端点都能单独验证// 健康检查 router.get(/health, async () { return { status: ok, timestamp: new Date().toISOString(), }; }); // JSON 对象响应 router.get(/api/hello, async ({ request }) { return { message: Hello, World! }; }); // 读 JSON body router.post(/api/user, async ({ request }) { const body await request.json(); return { processed: true }; }); // 路由参数 router.get(/api/posts/:category/:id, async ({ request, params }) { const { category, id } params; return { category, id }; }); // 纯文本 router.get(/api/text, async ({ request }) { return Hello World; }); // Blob router.get(/api/blob, async ({ request }) { return new Blob([Hello World], { type: text/plain }); }); // Uint8Array router.get(/api/uint8array, async ({ request }) { return new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); }); // 二进制流 router.get(/api/binary-stream, async ({ request }) { return new ReadableStream({ start(controller) { controller.enqueue( new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]) ); controller.close(); }, }); }); // 自定义 status 和 headers router.get(/api/custom, async ({ request }) { return new Response(JSON.stringify({ data: custom }), { status: 200, headers: { Content-Type: application/json, Custom-Header: value, }, }); }); // user 上下文读调用者自己的 KV仅经 puter.workers.exec() 调用时可用 router.get(/api/kv/user/get, async ({ request, user }) { const url new URL(request.url); const key url.searchParams.get(key); const value await user.puter.kv.get(key); return { value }; }); // 404 兜底 router.get(/*tag, async ({ params }) { return new Response( JSON.stringify({ error: Not found, path: params.tag, availableEndpoints: [/health, /api/hello, /api/posts/:category/:id], }), { status: 404, headers: { Content-Type: application/json }, } ); });每个片段都来自文档示例唯一改动是 404 兜底里availableEndpoints数组的内容——文档示例列的是它自己示例工程里的端点这里换成本文件实际定义的端点你自己写时列自己的即可。部署 worker在能使用 Puter.js 的环境puter.com 网页、应用或 Node 脚本里先把代码写入你账号下的文件再创建部署// 1. 把 worker 代码保存为你账号下的 my-worker.js await puter.fs.write(my-worker.js, workerCode); // 2. 按名称和文件路径部署 const deployment await puter.workers.create(my-api, my-worker.js); console.log(Worker deployed at: ${deployment.url});workerName用my-api这类名称字母、数字、连字符、下划线filePath指向 Puter 账号里的 JS 文件路径。返回值是 WorkerDeployment 对象包含successBoolean是否部署成功、urlString部署后的地址、errorsArray部署错误列表三个字段。等 530 秒传播完成再测试。替代路径二选一即可文档均支持在 puter.com 上建好.js文件后右键选择Publish as Worker起个名字点击 Publishworker 即上线在https://your-worker.puter.work见 Workers 总览。用 Puter CLInpm install -g heyputer/cli然后puter worker deploy [file] [name]两个参数都可省略省略时 CLI 会交互式提示输入文件与名称。文档注明 CLI 目前处于 beta0.x命令和行为可能变化。另外worker 的名称和 URL 终身不变后续改代码要覆盖它的源文件见 更新 worker不要换新名再 create否则旧 worker 还挂在旧 URL 上。验证各端点公开端点用普通fetch验证文档给出的测试写法// GET const response await fetch(${deployment.url}/api/hello); console.log(await response.text()); // 路由参数请求 /api/posts/tech/42 const post await fetch(${deployment.url}/api/posts/tech/42); console.log(await post.json()); // 文档示例{ category: tech, id: 42 }deployment.url即上一步create()返回的url。按各端点代码的返回值预期能核对到/api/hello返回 JSON{ message: Hello, World! }/api/posts/tech/42返回{ category: tech, id: 42 }文档明确给出该匹配结果/api/text是纯文本Hello World/api/custom的响应头里带Custom-Header: value请求一个不存在的路径会命中/*tag兜底得到 404 JSON。POST 端点按 router 文档的测试模式const postResponse await puter.workers.exec(${workerUrl}/api/user, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ key: test, value: hello }), }); const postData await postResponse.json(); console.log(postData); // 返回 { processed: true }验证user上下文必须走puter.workers.exec()因为只有它会自动带上用户会话puter-auth头// workerUrl 即 create() 返回的部署 URL例如 https://my-api.puter.work const response await puter.workers.exec(${workerUrl}/api/kv/user/get?keyhello); const data await response.json(); console.log(data); // 文档示例返回形态{ value }key后的hello是要在调用者自己的 KV 里查询的键可换成你已写入的值。value字段取到什么取决于该用户 KV 里实际的数据文档只给出了{ value }这个返回形态没有承诺固定取值。边界与限制user只在puter.workers.exec()调用链上存在。用裸fetch请求依赖user.puter的端点时拿不到调用者上下文如果端点必须鉴权文档示例的做法是判断user.puter缺失后返回 401 的Response。路由参数和通配符捕获的值永远是字符串数值转换自己做。CORS 由运行时自动处理每个响应都带Access-Control-Allow-Origin: *预检OPTIONS请求自动应答。只有当你自己定义OPTIONShandler 时才接管预检、需要自己补齐响应头若还要配合puter.workers.exec()使用必须把puter-auth列进Access-Control-Allow-Headers否则预检失败、请求根本到不了 worker。worker 文件上限 10MB名称规则、530 秒传播窗口见「准备条件」。可选给路由参数加类型推导。heyputer/worker-types包是纯开发期工具不进入部署产物安装后从路径字面量推断params的键npm install --save-dev heyputer/worker-typesrouter.get(/posts/:postId/comments/:commentId, ({ params }) { params.postId; // string params.commentId; // string });该包声明的 handler 事件包括request、params、user/requestor后者与user同源仅在带puter-auth头调用时存在全局对象含router、memy、myself为别名、puter_auth、puter_endpoint详见 types 文档。改动与重新部署worker 名称和 URL 终身不变。要更新代码用puter.workers.get(my-api)查到file_path把新代码写回该文件即触发同 URL 重新部署已有的调用方不需要改任何地址见 create 文档 的 Updating a worker 一节const info await puter.workers.get(my-api); await puter.fs.write(info.file_path, updatedWorkerCode);【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价