基于hapi 16.6.2与h2o2 5.2.0,如何在h2o2代理中添加请求头Cookie值?
我之前在维护老项目的时候刚好处理过hapi 16 + h2o2 5.x的代理Cookie传递问题,踩过几个坑,给你分享下解决方案:
核心思路:操作上游请求要找对对象
在hapi 16搭配h2o2 5.x的场景下,修改上游请求头必须通过request.proxy对象,而不是直接修改原始的request对象。你用onRequest报错,大概率是没找对这个入口,或者遗漏了关键的回调步骤。
完整可运行的示例代码
下面是一个经过验证的代理路由配置,能把客户端的Cookie完整传递到上游API,同时处理会话维持的反向传递:
const Hapi = require('hapi'); const H2o2 = require('h2o2'); // 初始化hapi服务 const server = new Hapi.Server(); server.connection({ port: 3000 }); // 注册h2o2代理插件 server.register(H2o2, (err) => { if (err) throw new Error(`注册插件失败:${err.message}`); // 配置代理路由 server.route({ method: ['GET', 'POST'], // 根据你的需求调整请求方法 path: '/proxy/{path*}', // 匹配所有/proxy开头的请求 handler: { proxy: { uri: 'https://your-upstream-api.com/{path}', // 替换成你的上游API地址 passThrough: false, // 关闭自动头传递,避免和自定义逻辑冲突 onRequest: (request, reply, settings, ttl) => { // 从客户端请求头中提取Cookie const clientCookie = request.headers.cookie; if (clientCookie) { // 将Cookie设置到上游请求的头中 request.proxy.headers.cookie = clientCookie; } // 必须调用continue()让请求继续流转,否则会挂起报错 reply.continue(); }, onResponse: (err, res, request, reply, settings, ttl) => { if (err) return reply(err); // 把上游返回的Set-Cookie头传递回客户端,维持会话 const upstreamSetCookie = res.headers['set-cookie']; if (upstreamSetCookie) { reply.response(res).header('Set-Cookie', upstreamSetCookie); } else { reply.response(res); } } } } }); // 启动服务 server.start((err) => { if (err) throw new Error(`服务启动失败:${err.message}`); console.log(`代理服务已启动:${server.info.uri}`); }); });
常见错误排查(你大概率踩了其中一个)
- 忘记调用
reply.continue():onRequest钩子必须调用这个方法,否则请求会被中断,直接抛出超时或请求挂起的错误,这是新手最容易犯的错。 - 错误修改
request.headers:原始的request.headers是客户端的请求头,修改它不会影响上游API的调用,必须修改request.proxy.headers才是操作上游请求的头。 passThrough选项冲突:如果把passThrough设为true,h2o2会自动传递大部分请求头,可能会和你自定义的Cookie逻辑冲突,建议设为false手动控制。- Cookie编码问题:如果客户端Cookie包含特殊字符,确保没有被错误转义,h2o2默认会处理头的编码,但如果有问题,可以用
encodeURIComponent手动处理后再设置。
如果按照上面的代码还是报错,建议把具体的错误信息贴出来,但根据我的经验,90%的情况都是上面列的前两个问题。
内容的提问来源于stack exchange,提问作者srgbnd
相关产品推荐
相关产品推荐

