惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
D
DataBreaches.Net
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
L
LangChain Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
Recent Announcements
Recent Announcements
Jina AI
Jina AI
G
Google Developers Blog
腾讯CDC
博客园_首页
博客园 - 【当耐特】

蚊子的前端博客

微说 | 有的人觉得只要不考XX,一定能考好!-蚊子的前端博客 微说 | 春天来了-蚊子的前端博客 明天和意外不知道哪个先来-蚊子的前端博客 微说 | 既然错过了路口,就及时止损,重新规划路线上路-蚊子的前端博客 微说 | 2025年的出生人口数是792万-蚊子的前端博客 微说 | 工作年终总结,让写对接的接口的数量?-蚊子的前端博客 微说 | 温家宝:没有政治体制改革的成功 经济体制改革不可能进行到底-蚊子的前端博客 微说 | 违法犯罪了该不该被禁言?-蚊子的前端博客 微说 | 不明白为什么在推荐去俄罗斯旅游-蚊子的前端博客 微说 | 易中天论骗子-蚊子的前端博客 微说 | 一场大风吹散了秋天-蚊子的前端博客 微说 | 既要、又要、还要、更要!-蚊子的前端博客 又是一年的国庆雨季-蚊子的前端博客 微说 | 预估下2025年的出生人口数据-蚊子的前端博客 微说 | 可惜了我那些小时候的书本-蚊子的前端博客 微说 | 牛马有的是,驴不够了!-蚊子的前端博客 微说 | 能否有一条非户口也能高考的路-蚊子的前端博客 微说 | 小聊中医-蚊子的前端博客 微说 | 将要制作的一款新产品-蚊子的前端博客 微说 | 做人要有信-蚊子的前端博客 微说 | 好一个正义联盟-蚊子的前端博客 微说 | 都是见过吃过的主儿-蚊子的前端博客 微说 | 追求8小时工作制有错吗?-蚊子的前端博客 微说 | 如果尖锐的批评完全消失-蚊子的前端博客 微说 | 很好!-蚊子的前端博客 微说 | 封禁用户可以,但要告知具体原因-蚊子的前端博客 微说 | 面朝大海,春暖花开-蚊子的前端博客 微说 | 程序员的悲哀是什么?-蚊子的前端博客 微说 | 2025年出生人口的预测-蚊子的前端博客 前端在 LiveKit 中如何获取所有的参与者-蚊子的前端博客
http-proxy-middleware 的注意事项-蚊子的前端博客
author · 2022-04-28 · via 蚊子的前端博客

这篇文章不是 http-proxy-middleware 的使用教程,关于如何使用,还请参考官方教程。主要是说下自己之前使用时的注意事项。

1. 无法继续流转路由 #

如我们在使用 express 等框架时,会声明多个路由的,有的路由是用来处理业务逻辑,有的是收集相关信息,有的是用作拦截器等。

import { createProxyMiddleware } from 'http-proxy-middleware';
import express from 'express';

const app = express();

app.use('*', createProxyMiddleware());
app.use('*', () => {
  console.log('after createProxyMiddleware'); // 无法输出
});

const port = Number(process.env.PORT) || 3001;
const ip = process.env.IP || '127.0.0.1';
app.listen(port, ip, () => {
  const msg = `[server]: Server is running at http://${ip}:${port}`;
  console.log(msg);
});

若上面 ↑ 的代码,在对*进行拦截请求后,后续的路由服务将不再执行。因此对该路由的一些处理,应当放在 http-proxy-middleware 的前面。

我们从源码 ↓ 中就可以看到,createProxyMiddleware()返回的是一个 middleware 方法,即对路由的处理方法:

// https://github.com/chimurai/http-proxy-middleware/blob/35ac1dbd29ff0953f978373dd6add081819087de/src/index.ts#L4
export function createProxyMiddleware(options: Options): RequestHandler {
  const { middleware } = new HttpProxyMiddleware(options);
  return middleware;
}

而在 middlware 的方法 ↓ 中可以看到,若代理过程是正常的,则不会再执行next()的逻辑。

// https://github.com/chimurai/http-proxy-middleware/blob/35ac1dbd29ff0953f978373dd6add081819087de/src/http-proxy-middleware.ts#L40
export class HttpProxyMiddleware {
  public middleware: RequestHandler = async (req, res, next?) => {
    if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
      try {
        const activeProxyOptions = await this.prepareProxyRequest(req);
        debug(`proxy request to target: %O`, activeProxyOptions.target);
        this.proxy.web(req, res, activeProxyOptions);
      } catch (err) {
        next && next(err);
      }
    } else {
      next && next();
    }
  }
}

因此,后续的路由不会再接收请求。

2. onProxyRes 无法处理 content-length 为 0 的数据 #

我们可以在 onProxyRes 中对获取到的数据进行二次处理,然后再返回。如官方给到的样例intercept-and-manipulate-responses,将 Hello 替换为 GoodBye:

const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');

const proxy = createProxyMiddleware({
  /**
   * IMPORTANT: avoid res.end being called automatically
   **/
  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  /**
   * Intercept response and replace 'Hello' with 'Goodbye'
   **/
  on: {
    proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
      const response = responseBuffer.toString('utf8'); // convert buffer to string
      return response.replace('Hello', 'Goodbye'); // manipulate response and return the result
    }),
  },
});

但是,若代理转发地址返回的数据,response header 中,不存在content-length字段,或者该字段的值为 0。则 onProxyRes 中的 responseBuffer 为空,无法处理处理数据。

如一些 CDN 或者 COS 上的数据,他为了快速响应,或者使用了 chunked 编码(transfer-encoding: chunked),在返回数据时,通常没有 content-length 这个字段。