http-proxy-middleware中onProxyRes部分场景失效问题咨询
问题根因
不是onProxyRes在响应返回完成前提前触发,核心是遗漏了必要配置,且没有适配Notion站点的响应规则,这也是代理Google时功能正常、切换到Notion就失效的原因:
- Notion 站点默认对所有文本类响应开启 gzip/brotli 压缩,默认配置下
responseInterceptor不会自动解压压缩后的响应流,因此拿到的responseBuffer为空。 - Notion 存在强制HTTPS、域名跳转的3xx重定向逻辑,默认配置下代理不会跟随重定向,拿到的跳转响应本身就没有实体内容。
- 自定义响应头的设置逻辑写在拦截器回调内,当拦截逻辑因为空buffer执行异常时,头设置也不会生效,最终代理会自动兜底返回未修改的原始响应。
修复方案
在代理配置中补全必要参数,完整可用代码如下:
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware'); const proxy = createProxyMiddleware({ // 注意Notion强制HTTPS,target不要写HTTP地址 target: "https://www.notion.so", changeOrigin: true, // 关键配置1:自动跟随目标站点的3xx重定向 followRedirects: true, // 关键配置2:自动解压gzip/brotli压缩的响应,保证拦截器能拿到完整非空buffer decompress: true, selfHandleResponse: true, onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => { // 设置自定义响应头 res.setHeader("custom-header", "header-value"); // 仅处理文本/JSON类响应,避免图片、字体等二进制资源转码损坏 const contentType = proxyRes.headers['content-type'] || ''; if (!contentType.includes('text/') && !contentType.includes('application/json')) { return responseBuffer; } const response = responseBuffer.toString('utf8'); // 按业务需求替换响应内容 return response.replaceAll('Hello', 'GoodBye'); }), });
额外注意事项
- 如果代理后页面加载出现跨域、嵌入限制问题,可以在拦截逻辑中移除目标站点返回的
content-security-policy、x-frame-options等安全限制类响应头。 - 如果需要代理SSE、大文件流式下载场景,不要使用
responseInterceptor,该拦截器会等待完整响应接收完成才触发,会导致流式传输卡顿、内存占用过高,这类场景需要自行监听响应流事件逐块处理。
内容的提问来源于stack exchange,提问作者Matías González
相关产品推荐
相关产品推荐

