这篇文章不是 http-proxy-middleware 的使用教程,关于如何使用,还请参考官方教程。主要是说下自己之前使用时的注意事项。 如我们在使用 express 等框架时,会声明多个路由的,有的路由是用来处理业务逻辑,有的是收集相关信息,有的是用作拦截器等。 若上面 ↑ 的代码,在对 我们从源码 ↓ 中就可以看到,createProxyMiddleware()返回的是一个 middleware 方法,即对路由的处理方法: 而在 middlware 的方法 ↓ 中可以看到,若代理过程是正常的,则不会再执行 因此,后续的路由不会再接收请求。 我们可以在 onProxyRes 中对获取到的数据进行二次处理,然后再返回。如官方给到的样例intercept-and-manipulate-responses,将 Hello 替换为 GoodBye: 但是,若代理转发地址返回的数据,response header 中,不存在 如一些 CDN 或者 COS 上的数据,他为了快速响应,或者使用了 chunked 编码(transfer-encoding: chunked),在返回数据时,通常没有 content-length 这个字段。1. 无法继续流转路由 #
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
的前面。// 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;
}
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 的数据 #
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
}),
},
});
content-length
字段,或者该字段的值为 0。则 onProxyRes 中的 responseBuffer 为空,无法处理处理数据。
版权属于:
加速器之家
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
评论