You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用webpack-dev-server重写同域请求路径?遇ETIMEDOUT问题

Webpack-dev-server 代理URL重写异常排查

问题背景

需求是通过webpack-dev-server将匹配/**/locales/**/*.json的请求URL重写,例如把some.domain.com/subpath/locales/another/file.json改写为some.domain.com/locales/file.json。

此前配置正常,代码迁移后先后出现EHOSTUNREACH和ETIMEDOUT错误,错误日志:

<e> [webpack-dev-server] [HPM] Error occurred while proxying request some.domain.com/locales/file.json to https://some.domain.com/ [ETIMEDOUT] (https://nodejs.org/api/errors.html#errors_common_system_errors)

已通过hosts文件解析some.domain.com,当前配置代码如下:

const HOST_DOMAIN = 'some.domain.com'

return {
  devServer: {
    server: { type: "https" },
    port: 443,
    compress: true,
    allowedHosts: "all",
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    client: {
      webSocketURL: `auto://${HOST_DOMAIN}/ws`,
    },
    proxy: {
      '/**/locales/**/*.json': {
        target: 'https://' + HOST_DOMAIN,
        pathRewrite: function (path) {
          const parts = path.split('/');
          return '/locales/' + parts.pop();
        },
        secure: false
      }
    },
    static: [
      {
        directory: path.join(__dirname, "src/locales"),
        publicPath: `/locales`,
      },
    ],
  },
  // ...
}

已尝试设置originRewrite: true但无效,需确认:

  1. 该URL重写需求是否可行
  2. 当前配置是否正确
  3. 异常的原因

解答

1. 需求完全可行

webpack-dev-server的代理功能底层依赖http-proxy-middleware,支持复杂路径匹配和自定义重写逻辑,你要实现的URL重写需求完全可以做到。

2. 当前配置的问题

  • 路径匹配规则有歧义:/**/locales/**/*.json这种glob匹配写法可能导致部分请求被错误拦截,或者匹配优先级出问题,不如正则表达式精确。
  • 代理循环是核心隐患:你的dev-server运行在some.domain.com:443,代理目标又是https://some.domain.com,加上hosts把这个域名指向本地,请求被代理后会直接打回本地dev-server,形成循环请求,最终就会出现超时或无法连接的错误。
  • static配置和代理冲突:static里把src/locales映射到/locales,当代理后的请求到/locales/file.json时,会优先读取本地静态文件,而不是转发到目标服务器,逻辑上会混乱。
  • pathRewrite逻辑虽能工作但不够健壮:path.split('/').pop()虽然能拿到最后一段文件名,但如果路径里有空字符串(比如开头的/),可能会出现意外情况,不过这不是当前报错的原因。

3. 失效原因

代码迁移后,要么是hosts配置变了(把域名指向了本地),要么是dev-server端口改成了443,或者依赖版本更新后http-proxy-middleware的匹配逻辑变了,这些都触发了代理循环的问题。之前配置正常,大概率是当时没有形成这种循环(比如dev-server用的是其他端口,或者hosts没指向本地)。

修正方案

首先解决代理循环问题(最关键)

有两种方式:

  • 改dev-server端口:把端口从443改成8443这类非标准HTTPS端口,同时调整webSocketURL:
    port: 8443,
    client: {
      webSocketURL: `auto://${HOST_DOMAIN}:8443/ws`,
    },
    
  • 绕开hosts解析:保持443端口,但代理目标直接用服务器真实IP,同时设置changeOrigin和Host头:
    target: 'https://目标服务器真实IP',
    changeOrigin: true,
    headers: {
      Host: HOST_DOMAIN
    }
    

优化路径匹配与重写

把glob匹配改成正则,更精确:

proxy: {
  '^/.*/locales/.*/.*\\.json$': { // 匹配任意前缀 + locales + 任意层级 + .json后缀的路径
    target: 'https://' + HOST_DOMAIN,
    pathRewrite: (path) => {
      // 提取文件名,重写成/locales/文件名.json
      const match = path.match(/([^/]+)\.json$/);
      return match ? `/locales/${match[1]}.json` : path;
    },
    secure: false,
    changeOrigin: true
  }
}

解决static和代理的冲突

如果不需要本地静态资源优先响应,给代理加bypass逻辑跳过static:

proxy: {
  '^/.*/locales/.*/.*\\.json$': {
    // ...其他配置
    bypass: () => false // 直接走代理,不触发static资源
  }
}

内容的提问来源于stack exchange,提问作者ricardo-dlc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:55:55