简体   繁体   English

Webpack Dev Server proxied GET 返回空 JSON object 当需要数据时

[英]Webpack Dev Server proxied GET returns empty JSON object when data is expected

I'm running a local instance of FoundryVTT which, among a lot of other things, serve two resources:我正在运行FoundryVTT的一个本地实例,除其他外,它提供两种资源:

  1. http://localhost:30000/modules/_dev-mode/lang/en.json (5.6 kB JSON) http://localhost:30000/modules/_dev-mode/lang/en.json (5.6 kB JSON)
  2. http://localhost:30000/lang/en.json (24.9 kB JSON) http://localhost:30000/lang/en.json (24.9 kB JSON)

I have setup webpack-dev-server to start a proxy with hot reload, which I want to use for development.我已经设置webpack-dev-server来启动带有热重载的代理,我想将其用于开发。 I have enabled all logging I could find to troubleshoot the problem I'm experiencing:我已启用所有我能找到的日志记录来解决我遇到的问题:

devServer: {
  client: {
    logging: "verbose",
  },
  hot: true,
  devMiddleware: {
    writeToDisk: true,
  },
  static: false,
  proxy: {
    context: (pathname, req) => {
      // Don't proxy hot reload
      const proxy = !pathname.match("^/ws");
      console.log("[CONTEXT]", pathname, proxy);
      return proxy;
    },
    target: "http://localhost:30000",
    ws: true,
    logLevel: "debug",
    changeOrigin: true,
    //selfHandleResponse: true,
    onProxyReq: (proxyReq, req, res) => {
      try {
        const proxyHost = req?.headers?.host || "HOST?";
        const proxyUrl = `${req.protocol}://${proxyHost}${req.path}`;
        console.log(`[${req.method}] ${proxyUrl}`);
      } catch (error) {
        console.log("[ERROR]", "onProxyReq", error);
      }
    },
    onProxyRes: (proxyRes, req, res) => {
      try {
        const proxyHost = req?.headers?.host || "HOST?";
        const proxyUrl = `${req.protocol}://${proxyHost}${req.path}`;
        const targetHeader = proxyRes?.socket?._httpMessage?._header;
        const targetHost =
          /host:\s+(?<host>\S+)/.exec(targetHeader)?.groups?.host ||
          "HOST?";
        const url = `${proxyRes.req.protocol}//${targetHost}${proxyRes.req.path}`;
        const exchange = `[${req.method}] [${proxyRes.statusCode}] ${proxyUrl} -> ${url}`;
        console.log(exchange);
      } catch (error) {
        console.log("[ERROR]", "onProxyRes", error);
      }
    },
    onError: (err, req, res, target) => {
      console.log("[ERROR]", "onError", err, req, res, target);
    },
  },
},

I also run this with DEBUG = "express:*" to enable logging from Express.我还使用DEBUG = "express:*"运行它以启用从 Express 进行日志记录。

Accessing the first resource (http://localhost:30000/modules/_dev-mode/lang/en.json) via the proxy (http://localhost:8080/modules/_dev-mode/lang/en.json) returns the JSON as expected.通过代理(http://localhost:8080/modules/_dev-mode/lang/en.json)访问第一个资源(http://localhost:30000/modules/_dev-mode/lang/en.json)返回如预期的 JSON。

The devServer configuration logs: devServer配置日志:

[CONTEXT] /modules/_dev-mode/lang/en.json true
[GET] http://localhost:8080/modules/_dev-mode/lang/en.json
[GET] [200] http://localhost:8080/modules/_dev-mode/lang/en.json -> http://localhost:30000/modules/_dev-mode/lang/en.json

The Express debugging logs:快速调试日志:

express:router dispatching GET /modules/_dev-mode/lang/en.json +12m
express:router query  : /modules/_dev-mode/lang/en.json +1ms
express:router expressInit  : /modules/_dev-mode/lang/en.json +1ms
express:router compression  : /modules/_dev-mode/lang/en.json +1ms
express:router middleware  : /modules/_dev-mode/lang/en.json +0ms
express:router handler  : /modules/_dev-mode/lang/en.json +1ms

Accessing the second resource (http://localhost:30000/lang/en.json) via the proxy (http://localhost:8080/lang/en.json) does not work as expected.通过代理 (http://localhost:8080/lang/en.json) 访问第二个资源 (http://localhost:30000/lang/en.json) 无法按预期工作。 Instead of 24.9 kB it only returns {} .它只返回{}而不是 24.9 kB。

The devServer configuration logs nothing in this case.在这种情况下, devServer配置不记录任何内容。

The Express debugging logs (notice the handler row from the other example is missing): Express 调试日志(注意另一个示例中的处理程序行丢失了):

express:router dispatching GET /lang/en.json +4m
express:router query  : /lang/en.json +0ms      
express:router expressInit  : /lang/en.json +0ms
express:router compression  : /lang/en.json +1ms
express:router middleware  : /lang/en.json +0ms 

A guess is that the problem might be caused by the large JSON size and chunking.一个猜测是问题可能是由大的 JSON 大小和分块引起的。 If I skip the proxy the entire JSON is returned as expected.如果我跳过代理,则会按预期返回整个 JSON。 This is how the requests headers look like in the no-proxy case:这是无代理情况下请求标头的样子:

GET /lang/en.json HTTP/1.1
Host: localhost:30000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,sv;q=0.8
Cookie: session=5ec3bb8586ae5062804c72ae

And the response headers:以及响应标头:

HTTP/1.1 200 OK
X-Powered-By: Express
Cache-Control: no-cache
Accept-Ranges: bytes
Last-Modified: Sun, 06 Mar 2022 09:01:38 GMT
ETag: W/"15127-17f5e767fee"
Content-Type: application/json; charset=UTF-8
Vary: Accept-Encoding
Content-Encoding: gzip
Date: Mon, 21 Mar 2022 19:09:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

I feel like something is going wrong inside the proxy and I can't figure out what.我觉得代理内部出了点问题,我不知道是什么。 Is there something obviously incorrect with my setup, or some way for me to get more logs or info about what's happening?我的设置是否有明显不正确的地方,或者我可以通过某种方式获取更多日志或有关正在发生的事情的信息?

Debugged the proxy by enabling auto attach in Visual Studio Code.通过在 Visual Studio Code 中启用自动附加来调试代理。

The problem was that the proxy was serving the request to http://localhost:8080/lang/en.json using .../<project>/dist/lang/en.json instead of forwarding it to http://localhost:30000/lang/en.json .问题是代理正在使用.../<project>/dist/lang/en.json服务于http://localhost:8080/lang/en.json的请求,而不是将其转发到http://localhost:30000/lang/en.json

In this case, only requests for resources under /modules/<project> should be served from the folder .../<project>/dist .在这种情况下,仅应从文件夹.../<project>/dist提供对/modules/<project>下资源的请求。 Setting the publicPath solved this:设置publicPath解决了这个问题:

devServer: {
  devMiddleware: {
    publicPath: "/modules/<project>"
  }
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM