【问题标题】:angular-cli server - how to proxy API requests to another server?angular-cli server - 如何将 API 请求代理到另一台服务器?
【发布时间】:2016-09-07 11:05:41
【问题描述】:

使用 angular-cli ng serve 本地开发服务器,它为我的项目目录中的所有静态文件提供服务。

如何将我的 AJAX 调用代理到不同的服务器?

【问题讨论】:

    标签: angular angular-cli


    【解决方案1】:
    1. 添加proxy.conf.json,所有对/api的请求都会重定向到htt://targetIP:targetPort/api。
    {
      "/api": {
        "target": "http://targetIP:targetPort",
        "secure": false,
        "pathRewrite": {"^/api" : targeturl/api},
        "changeOrigin": true,
        "logLevel": "debug"
      }
    }
    
    1. 在 package.json 中,制作 "start": "ng serve --proxy-config proxy.conf.json"

    2. 在代码中 让 url = "/api/clnsIt/dev/78"; 这个 url 将被翻译成 http://targetIP:targetPort/api/clnsIt/dev/78。

    3. 您也可以通过填充 pathRewrite 来强制重写。 This is the link for details cmd/NPM 控制台将记录类似“从“/api/...”重写路径到“http://targeturl:targetPort/api/..”,而浏览器控制台将记录“http://loclahost/api”

    【讨论】:

      【解决方案2】:

      我将在下面的示例中解释您需要知道的

      {
        "/folder/sub-folder/*": {
          "target": "http://localhost:1100",
          "secure": false,
          "pathRewrite": {
            "^/folder/sub-folder/": "/new-folder/"
          },
          "changeOrigin": true,
          "logLevel": "debug"
        }
      }
      
      1. /folder/sub-folder/*: path 说:当我在我的 Angular 应用程序中看到这个路径时(该路径可以存储在任何地方),我想用它做点什么。 * 字符表示将包含子文件夹后面的所有内容。例如,如果您在 /folder/sub-folder/ 中有多种字体,* 会选择所有字体

      2. "target": "http://localhost:1100" for the path 使 target URL 成为主机/源,因此在后台我们将有 http ://localhost:1100/文件夹/子文件夹/

      3. “路径重写”:{ "^/文件夹/子文件夹/": "/new-folder/" }, 现在假设您要在本地测试您的应用程序,url http://localhost:1100/folder/sub-folder/ 可能包含无效路径:/folder/sub-folder/。您想将该路径更改为正确的路径,即 http://localhost:1100/new-folder/,因此 pathRewrite 将变得有用。它将排除应用程序中的路径(左侧)并包含新写入的路径(右侧)

      4. “安全”:表示我们使用的是 http 还是 https。如果目标属性中使用了 https,则将安全属性设置为 true,否则将其设置为 false

      5. "changeOrigin":仅当您的主机目标不是当前环境时才需要该选项,例如:localhost。如果您想将主机更改为 www.something.com,这将是代理中的目标,然后将 changeOrigin 属性设置为“true”:

      6. “logLevel”:属性指定开发人员是否希望在其终端/cmd 上显示代理,因此他将使用如图所示的“调试”值

      一般来说,代理有助于在本地开发应用程序。您为生产目的设置文件路径,如果您在项目中本地拥有所有这些文件,您可以只使用代理来访问它们,而无需在应用中动态更改路径。

      如果它有效,您应该在您的 cmd/终端中看到类似的内容。

      【讨论】:

      • 谢谢,这是当前 Angular 版本的正确答案。但是,只有当您的目标不是 localhost 时,才需要“changeOrigin”选项。您还需要通过运行标志来加载代理配置文件, ng serve --proxy-config proxy.conf.json 显然忽略了 package.json 中的标志(如前面的示例中所示)。
      【解决方案3】:

      如果有人正在寻找同一个目标或基于 TypeScript 的配置的多个上下文条目。

      proxy.conf.ts

      const proxyConfig = [
        {
          context: ['/api/v1', '/api/v2],
          target: 'https://example.com',
          secure: true,
          changeOrigin: true
        },
        {
          context: ['**'], // Rest of other API call
          target: 'http://somethingelse.com',
          secure: false,
          changeOrigin: true
        }
      ];
      
      module.exports = proxyConfig;
      

      ng serve --proxy-config=./proxy.conf.ts -o

      【讨论】:

        【解决方案4】:

        第 1 步:转到您的根文件夹创建 proxy.conf.json

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

        第2步:转到package.json在那个找到“start”下找到“scripts”

        "start": "ng serve --proxy-config proxy.conf.json",

        第 3 步:现在在您的 http

        中添加 /auth/

         return this.http
              .post('/auth/register/', { "username": 'simolee12', "email": 'xyz@gmail.com', "password": 'Anything@Anything' });
          }

        第 4 步:终端运行中的最后一步 npm 开始

        【讨论】:

          【解决方案5】:

          Cors-origin issue screenshot

          我的申请中遇到了 Cors 问题。参考上面的截图。添加代理配置后问题已解决。我的应用程序 url: localhost:4200 并请求 api url:"http://www.datasciencetoolkit.org/maps/api/geocode/json?sensor=false&address="

          允许 Api 端的 no-cors 权限。而且我无法在服务器端更改 cors-issue,我只能在 angular(客户端)进行更改。

          解决步骤:

          1. 在 src 文件夹中创建 proxy.conf.json 文件。
             {
                "/maps/*": {
                  "target": "http://www.datasciencetoolkit.org",
                  "secure": false,
                  "logLevel": "debug",
                  "changeOrigin": true
                }
              }
          
          1. 在 Api 请求中
          this.http
                .get<GeoCode>('maps/api/geocode/json?sensor=false&address=' + cityName)
                .pipe(
                  tap(cityResponse => this.responseCache.set(cityName, cityResponse))
                );
          

          注意:我们在 Api 请求中跳过了主机名 url,它会在发出请求时自动添加。每当更改 proxy.conf.js 时,我们都必须重新启动 ng-serve,然后只有更改才会更新。

          1. 在 angular.json 中配置代理
          "serve": {
                    "builder": "@angular-devkit/build-angular:dev-server",
                    "options": {
                      "browserTarget": "TestProject:build",
                      "proxyConfig": "src/proxy.conf.json"
                    },
                    "configurations": {
                      "production": {
                        "browserTarget": "TestProject:build:production"
                      }
                    }
                  },
          

          完成这些步骤后重新启动 ng-serve Proxy working correctly as expect refer here

          > WARNING in
          > D:\angular\Divya_Actian_Assignment\src\environments\environment.prod.ts
          > is part of the TypeScript compilation but it's unused. Add only entry
          > points to the 'files' or 'include' properties in your tsconfig.
          > ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ ** : Compiled
          > successfully. [HPM] GET
          > /maps/api/geocode/json?sensor=false&address=chennai ->
          > http://www.datasciencetoolkit.org
          

          【讨论】:

            【解决方案6】:

            2017 年更新

            现在可以使用更好的文档,您可以同时使用 基于 JSON 和 JavaScript 的配置:angular-cli documentation proxy

            https 代理配置示例

            {
              "/angular": {
                 "target":  {
                   "host": "github.com",
                   "protocol": "https:",
                   "port": 443
                 },
                 "secure": false,
                 "changeOrigin": true,
                 "logLevel": "info"
              }
            }
            

            据我所知,Angular 2.0 版本不建议使用 .ember-cli 文件设置代理。官方方式如下

            1. 编辑您的package.json 中的"start" 以查看下方

              "start": "ng serve --proxy-config proxy.conf.json",

            2. 在项目的根目录中创建一个名为 proxy.conf.json 的新文件,并在其中定义您的代理,如下所示

              {
                "/api": {
                  "target": "http://api.yourdomai.com",
                  "secure": false
                }
              }
              
            3. 重要的是你使用npm start而不是ng serve

            从这里阅读更多信息:Proxy Setup Angular 2 cli

            【讨论】:

            • 如何处理“不安全”的凭据。使用节点,我可以将 process.env.NODE_TLS_REJECT_UNAUTHORIZED 设置为 0 并将绕过该安全性,但我不知道如何使用 proxy.config.json 来做到这一点。这都是开发堆栈,我不介意感觉不安全
            • 拥有 "secure":false 应该可以,它应该是布尔值而不是字符串...我花了无数时间将其保持为 "false"
            • 这对我有用,但代理最终会变成 /api/api/person 之类的东西,知道为什么会这样吗?
            • 可以分享一下你的proxy.conf.json 让我看看吗?
            • proxy.conf.json 的文档在哪里?
            【解决方案7】:

            这对我来说已经很接近了。还得补充:

            "changeOrigin": true,
            "pathRewrite": {"^/proxy" : ""}
            

            完整的proxy.conf.json如下图:

            {
                "/proxy/*": {
                    "target": "https://url.com",
                    "secure": false,
                    "changeOrigin": true,
                    "logLevel": "debug",
                    "pathRewrite": {
                        "^/proxy": ""
                    }
                }
            }
            

            【讨论】:

            • 这应该是本地外部 API 参考的选择答案。此 pathRewrite 解决了引用外部 EP 时的问题,将引用替换为目标。
            【解决方案8】:

            请务必注意,代理路径将附加到您配置为目标的任何内容。所以这样的配置:

            {
              "/api": {
                "target": "http://myhost.com/api,
                ...
              }
            }
            

            http://localhost:4200/api 这样的请求将导致调用http://myhost.com/api/api。我认为这里的意图是在开发和生产环境之间没有两条不同的路径。您需要做的就是使用/api 作为您的基本 URL。

            所以正确的方法是简单地使用 api 路径之前的部分,在这种情况下只是主机地址:

            {
              "/api": {
                "target": "http://myhost.com",
                ...
              }
            }
            

            【讨论】:

              【解决方案9】:

              当您需要更大的灵活性时,这是另一种代理方式:

              您可以使用“路由器”选项和一些 javascript 代码来动态重写目标 URL。 为此,您需要在“start”脚本参数列表中指定一个 javascript 文件而不是 json 文件作为 --proxy-conf 参数:

              "start": "ng serve --proxy-config proxy.conf.js --base-href /"
              

              如上所示,如果您将 设置为 index.html 中的路径,则还需要将 --base-href 参数设置为 /。此设置将覆盖它,并且有必要确保 http 请求中的 URL 构造正确。

              那么你的proxy.conf.js中需要以下或类似的内容(不是json!):

              const PROXY_CONFIG = {
                  "/api/*": {
                      target: https://www.mydefaulturl.com,
                      router: function (req) {
                          var target = 'https://www.myrewrittenurl.com'; // or some custom code
                          return target;
                      },
                      changeOrigin: true,
                      secure: false
                  }
              };
              
              module.exports = PROXY_CONFIG;
              

              请注意,可以通过两种方式使用路由器选项。一种是当您分配一个包含键值对的对象时,其中键是要匹配的请求的主机/路径,值是重写的目标 URL。另一种方法是当您使用一些自定义代码分配函数时,这就是我在此处的示例中演示的内容。在后一种情况下,我发现仍然需要将目标选项设置为某个值才能使路由器选项起作用。如果您将自定义功能分配给路由器选项,则不使用目标选项,因此可以将其设置为 true。否则,它需要是默认的目标 URL。

              Webpack 使用 http-proxy-middleware,所以你会在那里找到有用的文档: https://github.com/chimurai/http-proxy-middleware/blob/master/README.md#http-proxy-middleware-options

              以下示例将使用自定义函数作为路由器从 cookie 中获取开发者名称以确定目标 URL:

              const PROXY_CONFIG = {
                  "/api/*": {
                      target: true,
                      router: function (req) {
                          var devName = '';
                          var rc = req.headers.cookie;
                          rc && rc.split(';').forEach(function( cookie ) {
                              var parts = cookie.split('=');
                              if(parts.shift().trim() == 'dev') {
                                  devName = decodeURI(parts.join('='));
                              }
                          });
                          var target = 'https://www.'+ (devName ? devName + '.' : '' ) +'mycompany.com'; 
                          //console.log(target);
                          return target;
                      },
                      changeOrigin: true,
                      secure: false
                  }
              };
              
              module.exports = PROXY_CONFIG;
              

              (cookie 是为 localhost 和路径 '/' 设置的,并且使用浏览器插件具有较长的有效期。如果 cookie 不存在,则 URL 将指向实时站点。)

              【讨论】:

                【解决方案10】:

                这是另一个工作示例 (@angular/cli 1.0.4):

                proxy.conf.json:

                {
                  "/api/*" : {
                    "target": "http://localhost:8181",
                    "secure": false,
                    "logLevel": "debug"
                  },
                  "/login.html" : {
                    "target": "http://localhost:8181/login.html",
                    "secure": false,
                    "logLevel": "debug"
                  }
                }
                

                运行:

                ng serve --proxy-config proxy.conf.json
                

                【讨论】:

                  【解决方案11】:

                  我们可以在这里找到 Angular-CLI 的代理文档:

                  https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md

                  在您的根文件夹中设置一个名为 proxy.conf.json 的文件后,编辑您的 package.json 以在 ng start 中包含代理配置。在脚本中添加“start”:“ng serve --proxy-config proxy.conf.json”后,运行 npm start 而不是 ng serve,因为这将忽略 package.json 中的标志设置。

                  angular-cli 的当前版本:1.1.0

                  【讨论】:

                    【解决方案12】:

                    编辑:这不再适用于当前的 ANGULAR-CLI

                    查看@imal hasaranga perera 的回答以获得最新的解决方案


                    angular-cli 中的服务器来自ember-cli 项目。要配置服务器,请在项目根目录中创建一个.ember-cli 文件。在其中添加您的 JSON 配置:

                    {
                       "proxy": "https://api.example.com"
                    }
                    

                    重新启动服务器,它将代理那里的所有请求。

                    例如,我在我的代码中向/v1/foo/123 发出相关请求,该请求正在https://api.example.com/v1/foo/123 处接收。

                    您还可以在启动服务器时使用标志: ng serve --proxy https://api.example.com

                    当前 angular-cli 版本:1.0.0-beta.0

                    【讨论】:

                    • 感谢您的回答@elwyn。是否可以仅代理匹配某些模式的 url,例如 '/api/v1/'?
                    • 我不确定 - 我不需要这样做。网络服务器只是引擎盖下的香草ember-cli(现在,无论如何),所以也许看看他们的文档?这个人似乎有一个自定义代理运行的例子:stackoverflow.com/q/30267849/227622
                    • 昨天做了。正如你所说,它只是香草 ember-cli。所以我创建了一个 ember 应用程序,在那里生成了一个代理(在 angular-cli 中还没有这样的生成器)并复制到我的 angular 应用程序中。效果很好。谢谢。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-11-22
                    • 2012-06-07
                    • 2012-04-23
                    • 2012-12-27
                    • 1970-01-01
                    • 2022-12-10
                    相关资源
                    最近更新 更多