ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

http-proxy-middleware v3 迁移指南:从 `context` 到 `pathFilter` 的路径匹配

2026/10/7 9:45:08 拓冰建站 浏览量
http-proxy-middleware v3 迁移指南:从 `context` 到 `pathFilter` 的路径匹配 后端API网关【免费下载链接】http-proxy-middleware:zap: The one-liner node.js http-proxy (httpxy) middleware for connect, express, next.js and more项目地址https://gitcode.com/gh_mirrors/ht/http-proxy-middleware点击查看免费下载导读http-proxy-middleware在 v3.0.0 中移除了 v2 时代的第一个位置参数context即路径匹配上下文将其能力整体迁移为配置对象中的pathFilter选项。本文以官方迁移说明recipes/context-matching.md为核心系统梳理这一破坏性变更的迁移写法并结合仓库源码src/path-filter.ts、recipes/pathFilter.md深入讲解pathFilter的全部匹配形态、底层实现与测试验证帮助你平滑升级、零遗漏地控制哪些请求该被代理。一、迁移背景v2 的context参数被移除在 v2 版本中createProxyMiddleware支持context 参数 options 对象的双参数写法第一个参数context用于限定只代理匹配该路径的请求// v2第一个位置参数是 context路径匹配上下文 createProxyMiddleware(/api, { target: http://localhost:3000, });进入 v3 后这一参数写法被彻底移除recipes/context-matching.md第一行即标注[BREAKING CHANGE]。迁移指南 MIGRATION_V3.md 中对此有明确记载Removedcontextargument —— Thecontextargument has been moved to option:pathFilter. Functionality did not change.context参数已迁移为pathFilter选项功能没有变化。这意味着迁移只是换了个书写位置匹配能力与行为完全一致。同时v3 还一并移除了只传 target 字符串的 shorthand 用法createProxyMiddleware(http://www.example.org)所有配置统一收敛到 options 对象中API 更加一致。迁移后的标准写法TL;DR// v3context 改为配置项 pathFilter createProxyMiddleware({ target: http://localhost:3000, pathFilter: /api, });pathFilter是可选配置src/types.ts 中Options接口声明自 v3.0.0 起引入在不方便使用框架原生中间件挂载middleware mounting的场景下用来精确收窄哪些请求需要走代理。二、pathFilter的完整用法六种匹配形态pathFilter的类型定义见 src/types.tsexport type FilterTReq extends http.IncomingMessage http.IncomingMessage | string | string[] | ((pathname: string, req: TReq) boolean | string | RegExpMatchArray | null);即单个字符串、字符串数组、或自定义函数三种大类。下面按官方配方 recipes/pathFilter.md 逐一展开。1. Path单个前缀路径匹配以/api开头的请求路径import { createProxyMiddleware } from http-proxy-middleware; const apiProxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: /api, }); // /api/foo/bar - http://localhost:3000/api/foo/bar2. Multi Path多前缀路径数组匹配以/api或/rest开头的请求import { createProxyMiddleware } from http-proxy-middleware; const apiProxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: [/api, /rest], }); // /api/foo/bar - http://localhost:3000/api/foo/bar // /rest/lorum/ipsum - http://localhost:3000/rest/lorum/ipsum3. Wildcard单个 glob 通配符匹配以/api/开头且以.json结尾的路径。http-proxy-middleware内部借助is-glob与micromatch完成 glob 匹配见 src/path-filter.ts 的依赖引入import { createProxyMiddleware } from http-proxy-middleware; const apiProxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: /api/**/*.json, });4. Multi Wildcard多个 glob 通配符多个 glob 模式可放在数组中同时生效import { createProxyMiddleware } from http-proxy-middleware; const apiProxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: [/api/**/*.json, /rest/**], });5. Wildcard / Exclusionglob 排除模式利用 micromatch 的!取反语法实现匹配所有foo/*.js但排除bar.jsimport { createProxyMiddleware } from http-proxy-middleware; const apiProxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: [foo/*.js, !bar.js], });6. Custom filtering自定义函数当内置匹配无法满足需求时可以传入函数接收请求的pathname与原始req对象返回真值即代理、假值即放行import { createProxyMiddleware } from http-proxy-middleware; const pathFilter function (pathname, req) { return pathname.match(^/api) req.method GET; }; const apiProxy createProxyMiddleware({ pathFilter: pathFilter, target: http://localhost:3000, });函数返回值类型为boolean | string | RegExpMatchArray | nullsrc/types.ts返回的字符串或正则匹配结果都会被Boolean()归一化为真值见下文源码剖析因此写return pathname.match(^/api)这种直接返回 match 结果的写法同样合法。三、源码剖析matchPathFilter的匹配流水线所有匹配逻辑都收敛在 src/path-filter.ts 的matchPathFilter()函数中它按类型分派依次尝试六种路径单字符串非 glob→matchSingleStringPath()取 URL 的pathname判断pathname.indexOf(pathFilter) 0即纯前缀匹配src/path-filter.ts。单 glob 字符串→matchSingleGlobPath()用 micromatch 匹配[pathname]数组。字符串数组全部非 glob→matchMultiPath()逐个前缀匹配命中任意一个即返回truesrc/path-filter.ts。字符串数组全部为 glob→matchMultiGlobPath()等价于用整个数组做一次 micromatch 匹配。自定义函数→ 提取pathname后调用pathFilter(pathname, req)结果经Boolean()转换返回src/path-filter.ts。以上都不满足→ 抛出HttpProxyMiddlewareError。pathname 的提取规则getUrlPathName()src/path-filter.ts通过new URL(uri, http://0.0.0.0)解析req.url并取其pathname。这带来两个关键行为自动忽略 query string/api/foo?token1只会拿/api/foo参与匹配单元测试should ignore query params验证了这一点test/unit/path-filter.spec.ts匹配的是req.url的 pathname在 Express 中该路径是相对于代理挂载点mount point的路径见 recipes/pathFilter.md 与 src/types.ts 的文档注释。默认值与边界行为matchPathFilter的默认参数是/src/path-filter.ts即未配置pathFilter时匹配所有请求而空数组[]会自然返回false表示不代理任何请求test/unit/path-filter.spec.ts。非法配置的错误处理path-filter.ts定义了两种错误码src/errors.ts 中HttpProxyMiddlewareError的code字段HPM_INVALID_PATH_FILTER_CONFIG传入null、数字、普通对象等非法类型时抛出src/path-filter.tsHPM_INVALID_PATH_FILTER_ARRAY_CONFIG数组内混用了普通前缀与 glob如[/api, !*.html]时抛出src/path-filter.ts因为前缀匹配与 glob 匹配是两套互斥的算法官方错误信息建议要么用[/api, /ajax]纯前缀数组要么用[/api/**, !**.html]纯 glob 数组。以上错误行为均有单元测试覆盖test/unit/path-filter.spec.tsnull、对象字面量、整数都会触发HPM_INVALID_PATH_FILTER_CONFIG混用数组触发HPM_INVALID_PATH_FILTER_ARRAY_CONFIG而字符串、数组、glob、glob 数组、函数均合法不抛错。四、在中间件中的调用链shouldProxypathFilter真正生效的位置在 src/http-proxy-middleware.ts 中普通 HTTP 请求中间件入口middleware首先执行this.shouldProxy(this.proxyOptions.pathFilter, req)命中才进入prepareProxyRequest()router 路由与 pathRewrite 重写阶段并调用this.proxy.web()转发未命中则直接next?.()放行给下游src/http-proxy-middleware.tsWebSocket 升级请求handleUpgrade同样先经shouldProxy过滤命中后调用this.proxy.ws()src/http-proxy-middleware.ts——这意味着pathFilter对 WebSocket 代理同样生效shouldProxy内部用try/catch包裹matchPathFilter匹配过程抛出的任何错误会被记录到日志并返回false即不代理避免异常把整个中间件链路打挂src/http-proxy-middleware.ts。从源码结构看v2 中context参数在内部正是被归一化为同样的匹配逻辑所以迁移指南才强调 Functionality did not change功能不变。五、实战完整迁移示例下面是一个把 v2 Express 应用升级到 v3 的完整对照// ---------- v2 ---------- const { createProxyMiddleware } require(http-proxy-middleware); app.use( /api, createProxyMiddleware(/api, { target: http://localhost:3000, changeOrigin: true, }) ); // ---------- v3 ---------- const { createProxyMiddleware } require(http-proxy-middleware); app.use( createProxyMiddleware({ target: http://localhost:3000, changeOrigin: true, pathFilter: /api, // 原 context 参数迁移至此 }) );如果目标路径需要去前缀例如把/api/users转发为/users可在 v3 中配合pathRewrite使用这也是 src/factory.ts 的官方示例组合const proxy createProxyMiddleware({ target: http://localhost:3000, pathFilter: /api, pathRewrite: { ^/api/: /, }, });常见升级报错排查升级后如果代码仍沿用 v2 双参数写法TypeScript 会直接报类型错误createProxyMiddleware签名只接受 options 对象见 src/factory.ts。运行期则可能遇到症状原因处理请求全部 404 / 未代理忘了把/api写进pathFilter补上pathFilter: /api报错HPM_INVALID_PATH_FILTER_ARRAY_CONFIG数组中混用了普通路径和 glob拆成纯前缀数组或纯 glob 数组自定义函数不生效函数抛异常shouldProxy已捕获并记录日志检查logger.error输出六、测试验证从单元到端到端仓库对pathFilter的保障是双层的单元测试test/unit/path-filter.spec.ts 覆盖了字符串前缀含空串匹配全部、必须以/开头、前缀出现在中间不算命中、多前缀、单/多 glob含**、扩展名匹配、根目录限定、query 忽略、!取反、自定义函数真值/假值、非法配置抛错等数十个用例端到端测试test/e2e/http-proxy-middleware.spec.ts 验证了真实请求链路函数返回true时响应体原样代理回来HELLO WEB返回false时不代理下游返回 404test/e2e/hono.spec.ts 与 test/e2e/express-router.spec.ts 则验证了pathFilter在 Hono、Express Router 等不同框架下的行为一致性。这些测试同时是排查匹配行为的活文档——当你对某个 glob 写法是否命中存疑时对照 test/unit/path-filter.spec.ts 中的用例即可得到确定答案。七、小结从context到pathFilter的迁移本质是一次位置与命名的统一v3 把所有配置收敛进 options 对象pathFilter完整继承了 v2context的全部匹配语义前缀、多前缀、glob、多 glob、排除、自定义函数并在类型安全、错误码与测试覆盖上做得更严谨。升级时只需记住一条规则把createProxyMiddleware(/api, options)改写为createProxyMiddleware({ ...options, pathFilter: /api })。更多用法细节可继续阅读仓库内的 recipes/pathFilter.md完整匹配配方与 MIGRATION_V3.mdv3 全部破坏性变更清单。赞分享后端API网关【免费下载链接】http-proxy-middleware:zap: The one-liner node.js http-proxy (httpxy) middleware for connect, express, next.js and more项目地址https://gitcode.com/gh_mirrors/ht/http-proxy-middleware点击查看免费下载相关推荐http-proxy-middleware 路径过滤指南pathFilter 从单路径到自定义函数的完整用法http proxy middleware 路径过滤指南pathFilter 从单路径到自定义函数的完整用法 pathFilter 是 http proxy后端API网关http-proxy-middleware 版本迁移指南从v2升级到v3的最佳实践http proxy middleware 版本迁移指南从v2升级到v3的最佳实践 前言 http proxy middleware 是一个功能强大的 Nod后端API网关doublestar v4 升级指南从 v3/v2/v1 迁移到基于 io/fs 的高性能路径匹配与 Glob 库doublestar v4 升级指南从 v3/v2/v1 迁移到基于 io/fs 的高性能路径匹配与 Glob 库 doublestar 是 Go 语言实现的机器学习深度学习数据可视化可观测性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考