【问题标题】:504 (Gateway Timeout) error when proxying in Angular app在 Angular 应用程序中代理时出现 504(网关超时)错误
【发布时间】:2021-12-21 19:19:53
【问题描述】:

我正在尝试设置 Angular 应用程序以使用 2 个不同的本地主机。

我在项目根目录中创建了一个backend 文件夹,并在其中添加了echo.php 文件。在项目根目录中,我还创建了具有以下内容的 proxy.conf.json:

{
  "/backend/**": {
    "target": "http://localhost:80",
    "secure": false

  }
}

我尝试通过以下方式获取 echo.php:

  ngOnInit(){
    this.http.get('http://localhost:4200/backend/echo.php').subscribe(data => {
      console.log(data);      
    });
  }

启动 Angular 应用程序:

ng serve --port 4200 --host 0.0.0.0 --proxy-config proxy.conf.json

在浏览器控制台中,我收到了504 error Gateway Timeout。在终端中,错误听起来有点不同:

[HPM] Error occurred while trying to proxy request /backend/echo.php from localhost:4200 to http://localhost:80 (ENOTFOUND)

我不知道我做错了什么。你能为我指出正确的方向吗? 我可以使用以下 url 直接访问非角(在端口 80 上运行)服务器上的文件:http://localhost/backend/echo.php

编辑:

echo.php:

<?php
echo "data from php";

【问题讨论】:

  • 如果您在直接使用后端时遇到错误,则该错误似乎与 Angular 无关。将问题标记为php 并包括您的 PHP 代码和相关配置而不是 Angular 代码,您会更幸运。 (你在使用一些 PHP 框架吗?包括那个)
  • 直接使用localhost/backend/echo.php 访问资源时没有收到任何错误。仅当从 localhost:4200 代理到 localhost:80 时才会抛出错误
  • 我刚刚尝试了您的代码,它可以在我的机器上运行。当您说"In Terminal, the error sounds a bit different" 时,您是使用curl 从终端调用您的服务器还是您的意思是ng serve 记录的消息?如果是 curl,您可以发布您使用的命令吗?另外,您在哪个系统/容器上运行它?
  • 使用 ng serve 时出现错误信息。我不确定系统/容器是什么意思。我在 OSX 上运行它:) 同时,我意识到添加 "changeOrigin":true 解决了这个问题(不知道为什么文档中没有提到它)。但你猜怎么着,问题还不止于此 :D stackoverflow.com/questions/47613765/… 。配置 Angular 真的应该这么痛苦吗?
  • 好的,问题终于解决了。这一次是好的 :D changeOrigin 并没有真正修复它。我更改了 GET 链接并在不知情的情况下实际提供静态 PHP 文件。更改资源链接后,甚至从未使用过代理。真正的问题是在 proxy.conf.json 中指定目标。我在下面发布了答案。

标签: angular


【解决方案1】:

经过很多很多小时后,我发现了真正的问题。它源于在 proxy.conf.json 中指定目标。这是正确的:

{
  "/backend/*": {
    "target": "http://127.0.0.1",
    "secure": false,
    "changeOrigin":true,
    "logLevel": "debug"
  }
}

这不是:

{
  "/backend/*": {
    "target": "http://localhost",
    "secure": false,
    "changeOrigin":true,
    "logLevel": "debug"
  }
}

这可能与无法自行执行 ng serve 有关。

ng serve 

命令返回错误:

getaddrinfo ENOTFOUND localhost
Error: getaddrinfo ENOTFOUND localhost
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)

这是一个老问题,我从来没有深入了解这个错误。相反,我只是使用ng serve --port 4200 --host 0.0.0.0 来绕过它。

如果有人能解释为什么这样做会很棒。我的/etc/hosts 文件有以下内容:

127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
192.168.1.1      router.hm
127.0.0.1 My-MBP # added by Apache Friends XAMPP

【讨论】:

  • 4 小时尝试解决完全相同的问题,我发现我必须在 OSX 上运行 ng serve --port 4200 --host 0.0.0.0 才能完成这项工作!很惊讶没有更多关于这个的信息!
  • 我发现我的 proxy.conf.json 中有错字。感谢引导我找到解决方案
【解决方案2】:

proxy.conf.json 文件

{
    "/api/*":{
    "target" : "http://127.0.0.1:1234",
    "changeOrigin" : true,
    "secure" : false
    }
}

更改 proxy.conf.json 文件并同时将 php 开发服务器运行为 127.0.0.1:1234 而不是 localhost:1234 为我解决了这个问题。

【讨论】:

    【解决方案3】:

    我在 Angular 应用中代理时看到此错误:504(网关超时)错误

    您可能会对这个答案感到惊讶,我发现我犯了一个非常愚蠢的错误并忽略了代理目标。错误是 proxy.json 中的一个简单拼写错误。

    目标设置为:locahost 而不是 localhost

    虽然听起来很傻,但我花了一个多小时在这上面,我的眼睛肯定需要检查一下。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    • 当然……添加了更多上下文
    【解决方案4】:

    我还没有尝试使用ng serve 进行代理,但对我有用的是将后端应用程序放在根目录中,并将 angular 部分放在文件夹名称 viewfront-end 或任何你喜欢的文件夹名称下的子目录中.在此处查看 Launch angular 4 from Hapi js 以了解类似问题,但使用的是 nodejs。如果您有任何问题,请随时询问更多详细信息。

    【讨论】:

      【解决方案5】:

      我不知道为什么,但proxy.conf.json 中的 url 顺序确实很重要。

      例如,如果您将您的网址'/api/person/getPerson' 放在/api 之后,那么我会得到与 OP 相同的错误:

          '/api': {
              target: 'http://localhost:800/',
              secure: false,
              logLevel: "debug",
              changeOrigin: true,
              agent: agent,
              onProxyRes: onProxyRes
          },
          '/api/person/getPerson': {
              target: 'http://localhost:88888/',
              secure: false,
              logLevel: "debug",
              changeOrigin: true,
              pathRewrite: {
                "^/api/person/getPerson": ""
              },
              onProxyRes(proxyRes, req, res) {
                res.json(
                  [
                    {
                      "id": "id",
                      "name": "Jon Skeet"
                    },
                  ]
                  );
                  return res;
              }
          }
      

      但是,如果将这个 url '/api/person/getPerson' 放在 '/api' 之前,那么它可以正常工作:

          '/api/person/getPerson': {
                  target: 'http://localhost:88888/',
                  secure: false,
                  logLevel: "debug",
                  changeOrigin: true,
                  pathRewrite: {
                    "^/api/person/getPerson": ""
                  },
                  onProxyRes(proxyRes, req, res) {
                    res.json(
                      [
                        {
                          "id": "id",
                          "name": "Jon Skeet"
                        },
                      ]
                );
                return res;
              }
          },
          '/api': {
              target: 'http://localhost:800/',
              secure: false,
              logLevel: "debug",
              changeOrigin: true,
              agent: agent,
              onProxyRes: onProxyRes
          },
      

      【讨论】:

        【解决方案6】:

        我已经使用超时重试来解决这个 504 错误,如相应的 get/post http 调用 retryWhen(error => error.delay(5000)).timeout(900000)

        【讨论】:

        • 欢迎来到 Stackoverflow。请详细说明这将如何帮助解决问题。如果您要发布一些代码,请使用代码块。
        • 对于 http 调用,如果我们收到网关超时的 504 错误,我们可以使用 retryWhen 在延迟后获取响应,而不是立即抛出异常。
        猜你喜欢
        • 1970-01-01
        • 2021-04-05
        • 2020-04-14
        • 2011-04-08
        • 2017-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        相关资源
        最近更新 更多