You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Cloudflare Workers的Hono JS上下文无法访问FetchEvent

问题:Hono JS + Cloudflare Workers 无法访问 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:23:20