在Cloudflare Workers的Hono JS上下文无法访问FetchEvent
我正在使用Hono JS开发Cloudflare Workers应用,切换到Hono后无法在上下文(c)中访问FetchEvent,但相同逻辑在使用itty router或标准Cloudflare Worker配置时可正常运行。
我的index.js代码片段:
const app = new Hono(); app.get('/backgroundsounds', async (c) => { const event = c.event console.log("Event is", event); return await handleBackgroundSoundsGetAll(c); }); export default app;
handleBackgroundSoundsGetAll函数代码:
export const handleBackgroundSoundsGetAll = async (c) => { const { MY_BUCKET } = c.env; const request = c.req; // 从Hono上下文获取请求对象 const cacheUrl = new URL(request.url); const cacheKey = new Request(cacheUrl.toString(), { method: 'GET' }); const cache = caches.default; const fileName = "backgroundsounds.json"; console.log("Checking cache for key", cacheKey); let response = await cache.match(cacheKey); console.log("Cache match result", response); // 从环境绑定访问R2存储桶 const backgroundSoundsJson = c.env.MY_BUCKET.get(fileName); console.log("Fetching object and ETag from R2 bucket in the background"); if (response) { console.log("Cache hit, serving response"); if (c.event) { c.event.waitUntil(...) } return response; } else { // 缓存未命中的额外处理逻辑 } };
运行时收到错误提示:This context has no FetchEvent。
请问有人遇到过类似问题吗?或者能指出我的实现中可能存在的问题?
方法1:手动包装Worker入口,传递FetchEvent
Hono默认导出的是简化版的FetchHandler,不会自动绑定FetchEvent到上下文。你可以手动编写Worker的fetch函数,将ctx(即FetchEvent)传递给Hono:
修改index.js:
const app = new Hono(); app.get('/backgroundsounds', async (c) => { return await handleBackgroundSoundsGetAll(c); }); // 手动导出fetch函数,传递request、env、ctx export default { async fetch(request, env, ctx) { return app.fetch(request, env, ctx); } };
这样Hono会自动将ctx绑定到上下文c的event属性,你就能正常访问c.event了。
方法2:使用Hono内置的waitUntil方法替代直接调用event.waitUntil
Hono提供了内置的c.waitUntil()方法,功能和原生FetchEvent.waitUntil()完全一致,不需要直接访问FetchEvent:
修改handleBackgroundSoundsGetAll中的对应逻辑:
if (response) { console.log("Cache hit, serving response"); // 直接使用c.waitUntil,无需依赖c.event c.waitUntil(backgroundSoundsJson); return response; }
这种方式更贴合Hono的设计风格,代码更简洁,也避免了依赖底层的FetchEvent。
为什么itty router可以正常运行?
itty router的常规用法是让开发者手动编写fetch函数并处理FetchEvent,所以你能直接拿到event;而Hono默认导出的是封装后的handler,隐藏了这一层逻辑,因此需要手动处理或使用Hono提供的替代方法。
内容的提问来源于stack exchange,提问作者scouech

