http-proxy-middleware 的注意事项
侧边栏壁纸
  • 累计撰写 1,061 篇文章
  • 累计收到 0 条评论

http-proxy-middleware 的注意事项

加速器之家
2024-10-20 / 0 评论 / 3 阅读 / 正在检测是否收录...

这篇文章不是 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 这个字段。

0

评论

博主关闭了当前页面的评论