news 2026/9/11 5:16:55

Puter Worker 中 me.puter 与 user.puter 两种上下文怎么选择?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Puter Worker 中 me.puter 与 user.puter 两种上下文怎么选择?

Puter Worker 中 me.puter 与 user.puter 两种上下文怎么选择?

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

在 Puter 中写 Serverless Worker 时,代码里能拿到两个.puter对象:全局对象me上的me.puter,以及路由 handler 参数user上的user.puter。它们分别指向不同的 Puter 账户资源,而且每一次 KV、FS、AI 调用都会按"你调了哪一个"来计费。选错上下文,最常见的后果是:本应落在用户自己存储里的数据被写进了开发者账户,或者反过来,在用户根本没传入会话的请求里访问user.puter导致运行时报错。

这篇文章适用于已经准备好一段 worker 代码、准备部署到*.puter.work子域(或在*.puter.site托管站点里写 dynamic worker)的场景。router 文档给出了两个上下文的定义与选择依据,puter.workers.exec() 文档说明user.puter如何被填充,User-Pays 模型文档解释计费边界。下文按"判断 → 写法 → 验证"的顺序展开。

两种上下文的定义与区别

根据 router 文档:

  • me.puter(worker 上下文)me是写 worker 代码时始终可用的全局对象,代表 worker 的拥有者(即你自己)。me.puter让你访问自己的 Puter 资源——KV、FS、AI 等。操作跑在你的账户上,费用由你承担。文档建议用它处理"共享应用数据、服务端逻辑、由你集中控制的资源"。
  • user.puter(user 上下文):路由 handler 接收的参数对象中有一个user属性,代表发起这次请求的用户。user.puter让你访问该用户自己的 Puter 资源——KV、FS、AI 等。它只有在 worker 通过puter.workers.exec()被调用时才可用——exec()会用该用户的 token 执行请求,这正是它填充user.puter的方式。

两者的核心差异在计费模型:User-Pays 模型意味着每个用户用自己的 Puter 账户覆盖其消耗的 AI、存储等资源。user.puter保持了这一默认模型——每个用户的数据留在他们自己的存储里、由他们付费,而你的逻辑仍在服务端运行;me.puter则把操作记在你的账户上。

一个补充边界:开发者本人使用自己的应用时同样受 User-Pays 模型约束,自己的用量由自己承担。

选择依据:哪类端点用哪个上下文

文档给出的选择标准可以归纳为:

场景用哪个原因(均来自文档)
共享应用数据、集中存储、服务端逻辑、由你控制的基础设施me.puter数据属于应用本身,不依附某个用户;费用由开发者承担
操作"发起请求的那个用户"自己的 KV/FS/AI 数据user.puter数据留在用户自己的存储里,计费给用户,维持 User-Pays 模型
同一个 worker 内两类需求都有混合使用文档明确支持在同一代码库里混用:部分端点读写自己的数据(me.puter),部分端点操作调用者的数据(user.puter

也就是说,选择粒度是按端点的,而不是整个 worker 二选一。例如文档中的 AI 端点示例就用user.puter.ai.chat执行对话(用户付费),同时把对话记录写进me.puter.kv用于分析(开发者付费),两个上下文在同一次请求里各干各的。

user.puter 的填充机制:必须经过 puter.workers.exec()

user.puter不是无条件存在的,这一点决定了两个实现细节:

调用侧:必须用puter.workers.exec(workerURL, options)而不是标准fetch()。exec 文档说明它会自动带上用户会话,options是标准的 RequestInit 对象,返回值是一个 resolve 为Response的 Promise。调用侧示例(文档原样):

puter.workers.exec('https://my-worker.puter.work');

完整的前端调用形态如下(来自 exec 文档,js.puter.com脚本引入是示例原样内容):

<script src="https://js.puter.com/v2/"></script> <script> (async () => { // Execute a worker and get the response const response = await puter.workers.exec('https://my-worker.puter.work'); const data = await response.text(); puter.print(`Response: ${data}`); })(); </script>

worker 侧的 CORS 约束:CORS 默认自动处理,每次响应都带Access-Control-Allow-Origin: *,预检OPTIONS请求也自动应答——puter.workers.exec()把用户 token 放在自定义的puter-auth头里发送,跨域开箱即用。但如果你自己定义了OPTIONShandler,就等于接管了预检处理,必须自己保证头正确;使用puter.workers.exec()时,Access-Control-Allow-Headers里必须列出puter-auth,否则预检失败、请求根本到不了 worker:

router.options("/*path", async () => { return new Response(null, { status: 204, headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization, puter-auth", }, }); });

同 worker 内混用两个上下文的写法

文档给出的对照示例:同一个 KV 操作,一个端点读调用用户的 KV(user 上下文),另一个读 worker 拥有者的 KV(worker 上下文):

// Read from the calling user's KV store (user context) 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 }; }); // Read from the worker owner's KV store (worker context) router.get("/api/kv/worker/get", async ({ request }) => { const url = new URL(request.url); const key = url.searchParams.get("key"); const value = await me.puter.kv.get(key); return { value }; });

两个实现细节来自文档示例,直接影响正确性:

  1. me.puter.kv的键加前缀。KV 集成示例中写入时执行me.puter.kv.set("myscope_" + key, value),注释写明要加"mandatory prefix so this wont blindly read the KV of the user's other data"(强制前缀,避免误读用户其他数据的 KV)。读写两个端点必须使用同一前缀。
  2. 依赖user.puter的端点要显式校验。文档的 AI 集成示例在操作前先检查认证:
// Require user authentication to prevent abuse if (!user || !user.puter) { return new Response( JSON.stringify({ error: "Authentication required", message: "This endpoint requires user authentication. Call this worker via puter.workers.exec() with your user token to use your own AI resources.", }), { status: 401, headers: { "Content-Type": "application/json" } } ); } // 通过校验后,使用用户的 AI 资源 const aiResponse = await user.puter.ai.chat(message);

这就是"选择"落到代码上的形态:端点声明自己需要哪种上下文,不满足时返回 401 并提示调用方改用puter.workers.exec()

部署后的测试与验证

router 文档的 "Testing Your Router" 一节给出的验证路径是:部署后通过puter.workers.exec()请求各端点并检查响应(以下workerUrl为文档示例中的 URL 形式,需替换为你自己部署得到的 worker URL):

const workerUrl = "https://your-worker.puter.work"; // Test GET endpoint const response = await puter.workers.exec(`${workerUrl}/api/hello`); const data = await response.json(); console.log(data); // Test POST endpoint const postResponse = await puter.workers.exec(`${workerUrl}/api/data`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: "test", value: "hello" }), }); const postData = await postResponse.json(); console.log(postData);

验证时可以据此判断上下文选择是否生效:

  • 通过puter.workers.exec()调用依赖 user 上下文的端点,user.puter可用,端点返回操作结果(如上文 KV 示例返回{ value });
  • 不经exec()的普通请求不带用户 token,user.puter不可用——带认证的端点应如文档示例那样返回 401 及其提示信息,而不是直接崩溃;
  • 使用me.puter的端点在两种调用方式下都应可用,数据落在 worker 拥有者账户下,且遵循你设定的键前缀。

worker 的部署方式见 Workers 总览:在 puter.com 上创建.js文件后右键 "Publish as Worker",或用 Puter CLI 执行puter worker deploy [file] [name](两个参数均可省略,省略时 CLI 会交互询问),部署后获得https://your-worker.puter.work形式的 URL。

限制与边界

  • user.puter的可用条件:只有经puter.workers.exec()调用的请求才有用户 token。任何"看起来是公开接口但实际依赖user.puter"的端点,都必须像文档示例那样先做!user || !user.puter检查并返回 401。
  • KV/AppData 命名空间:worker 以一个 app 的身份运行,其puter.kv与 AppData 访问受该身份约束;作为同一个 app 运行的多个 worker 共享同一个 namespace。用me.puter存共享数据、或部署多个 worker 前,需要先了解 Workers 总览中 "Worker identity and shared state" 的说明。
  • Dynamic workers 同样适用:托管在*.puter.site站点__workers/目录下的.worker.js文件使用完全相同的 router API 与全局对象,Dynamic Workers 文档明确me.puteruser.puter的规则原样适用,因此本文的选择标准对两种 worker 都成立。
  • 计费不可事后调整:每次操作按实际调用的.puter对象计费——me.puter的调用记在开发者账户,user.puter的调用记在发起请求的用户账户。选哪个上下文本质上是决定这笔费用由谁承担,写完代码后无法通过配置改派。

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 5:12:02

破解ZLibrary反爬机制:Python爬虫高级技巧

1. 项目背景与核心挑战ZLibrary作为全球最大的数字图书馆之一&#xff0c;其反爬机制经历了多次迭代升级。2023年最新统计显示&#xff0c;平台日均拦截异常请求超过1200万次&#xff0c;其中针对Python爬虫的识别准确率高达92%。这主要得益于其动态渲染验证、行为指纹分析和请…

作者头像 李华
网站建设 2026/9/11 5:09:45

铸造行业温度控制技术突破与应用实践

1. 铸造行业温度控制的痛点与挑战在铸造生产线上&#xff0c;金属熔液的温度控制精度直接决定了铸件质量和工艺稳定性。以某年产20万吨的大型球墨铸铁厂为例&#xff0c;其熔炼车间每天需要处理超过600吨铁水&#xff0c;温度波动超过15℃就会导致球化不良、缩松等缺陷&#xf…

作者头像 李华
网站建设 2026/9/11 5:07:54

Python魔法方法__imod__:原地取模运算详解

1. Python魔法方法__imod__深度解析在Python中&#xff0c;魔法方法&#xff08;Magic Methods&#xff09;是那些以双下划线开头和结尾的特殊方法&#xff0c;它们为类提供了运算符重载的能力。今天我们要重点讨论的是__imod__这个不太常见但非常有用的魔法方法。__imod__方法…

作者头像 李华
网站建设 2026/9/11 5:07:18

嵌入式Linux下Modbus RTU通信的四大硬核挑战与实战方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华