简体   繁体   English

angular-cli 服务器 - 如何将 API 请求代理到另一台服务器?

[英]angular-cli server - how to proxy API requests to another server?

With the angular-cli ng serve local dev server, it's serving all the static files from my project directory.使用angular-cli ng serve本地开发服务器,它为我的项目目录中的所有静态文件提供服务。

How can I proxy my AJAX calls to a different server?如何将我的 AJAX 调用代理到不同的服务器?

UPDATE 2017 2017 年更新

Better documentation is now available and you can use both JSON and JavaScript based configurations: angular-cli documentation proxy现在可以使用更好的文档,您可以使用基于 JSON 和 JavaScript 的配置: angular-cli 文档代理

sample https proxy configuration示例 https 代理配置

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

To my knowledge with Angular 2.0 release setting up proxies using .ember-cli file is not recommended.据我所知,Angular 2.0 版本不推荐使用 .ember-cli 文件设置代理。 official way is like below官方方式如下

  1. edit "start" of your package.json to look below编辑package.json "start"以查看下面

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

  2. create a new file called proxy.conf.json in the root of the project and inside of that define your proxies like below在项目的根目录中创建一个名为proxy.conf.json的新文件,并在其中定义您的代理,如下所示

    { "/api": { "target": "http://api.yourdomai.com", "secure": false } }
  3. Important thing is that you use npm start instead of ng serve重要的是你使用npm start而不是ng serve

Read more from here : Proxy Setup Angular 2 cli从这里阅读更多信息:代理设置 Angular 2 cli

I'll explain what you need to know on the example below:我将在下面的示例中解释您需要了解的内容:

{
  "/folder/sub-folder/*": {
    "target": "http://localhost:1100",
    "secure": false,
    "pathRewrite": {
      "^/folder/sub-folder/": "/new-folder/"
    },
    "changeOrigin": true,
    "logLevel": "debug"
  }
}
  1. /folder/sub-folder/ *: path says: When I see this path inside my angular app (the path can be stored anywhere) I want to do something with it. /folder/sub-folder/ *: path 说:当我在我的 angular 应用程序中看到这条路径时(路径可以存储在任何地方)我想用它做点什么。 The * character indicates that everything that follows the sub-folder will be included. * 字符表示将包括子文件夹之后的所有内容。 For instance, if you have multiple fonts inside /folder/sub-folder/ , the * will pick up all of them例如,如果您在/folder/sub-folder/ 中有多种字体,则 * 将拾取所有字体

  2. "target" : "http://localhost:1100" for the path above make target URL the host/source, therefore in the background we will have http://localhost:1100/folder/sub-folder/ "target" : "http://localhost:1100" 上面的路径使目标URL 成为主机/源,因此在后台我们将有 http://localhost:1100/folder/sub-folder/

  3. "pathRewrite ": { "^/folder/sub-folder/": "/new-folder/" }, Now let's say that you want to test your app locally, the url http://localhost:1100/folder/sub-folder/ may contain an invalid path: /folder/sub-folder/. "pathRewrite ": { "^/folder/sub-folder/": "/new-folder/" }, 现在假设你想在本地测试你的应用程序,url http://localhost:1100/folder/sub -folder/ 可能包含无效路径:/folder/sub-folder/。 You want to change that path to a correct one which is http://localhost:1100/new-folder/, therefore the pathRewrite will become useful.您想将该路径更改为正确的路径,即 http://localhost:1100/new-folder/,因此 pathRewrite 将变得有用。 It will exclude the path in the app(left side) and include the newly written one (right side)它将排除应用程序中的路径(左侧)并包含新编写的路径(右侧)

  4. "secure" : represents wether we are using http or https. "secure" :代表我们使用的是 http 还是 https。 If https is used in the target attribute then set secure attribute to true otherwise set it to false如果在目标属性中使用了 https,则将安全属性设置为 true 否则将其设置为 false

  5. "changeOrigin" : option is only necessary if your host target is not the current environment, for example: localhost. "changeOrigin" :仅当您的主机目标不是当前环境时才需要该选项,例如:localhost。 If you want to change the host to www.something.com which would be the target in the proxy then set the changeOrigin attribute to "true":如果要将主机更改为www.something.com ,这将是代理中的目标,则将 changeOrigin 属性设置为“true”:

  6. "logLevel" : attribute specifies wether the developer wants to display proxying on his terminal/cmd, hence he would use the "debug" value as shown in the image "logLevel" : 属性指定开发人员是否希望在他的终端/cmd 上显示代理,因此他将使用 "debug" 值,如图所示

In general, the proxy helps in developing the application locally.通常,代理有助于在本地开发应用程序。 You set your file paths for production purpose and if you have all these files locally inside your project you may just use proxy to access them without changing the path dynamically in your app.您为生产目的设置文件路径,如果您在项目中本地拥有所有这些文件,您可以使用代理来访问它们,而无需在应用程序中动态更改路径。

If it works, you should see something like this in your cmd/terminal.如果它有效,你应该在你的 cmd/终端中看到类似的东西。

在此处输入图片说明

This was close to working for me.这接近于为我工作。 Also had to add:还得补充:

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

Full proxy.conf.json shown below:完整的proxy.conf.json如下所示:

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

EDIT: THIS NO LONGER WORKS IN CURRENT ANGULAR-CLI编辑:这不再适用于当前的 Angular-CLI

See answer from @imal hasaranga perera for up-to-date solution请参阅@imal hasaranga perera 的答案以获取最新解决方案


The server in angular-cli comes from the ember-cli project. angular-cli的服务器来自ember-cli项目。 To configure the server, create an .ember-cli file in the project root.要配置服务器,请在项目根目录中创建一个.ember-cli文件。 Add your JSON config in there:在那里添加您的 JSON 配置:

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

Restart the server and it will proxy all requests there.重新启动服务器,它将代理那里的所有请求。

For example, I'm making relative requests in my code to /v1/foo/123 , which is being picked up at https://api.example.com/v1/foo/123 .例如,我在我的代码中向/v1/foo/123发出相关请求,该请求在https://api.example.com/v1/foo/123被获取。

You can also use a flag when you start the server: ng serve --proxy https://api.example.com你也可以在启动服务器时使用一个标志: ng serve --proxy https://api.example.com

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

Here is another way of proxying when you need more flexibility:当您需要更多灵活性时,这是另一种代理方式:

You can use the 'router' option and some javascript code to rewrite the target URL dynamically.您可以使用 'router' 选项和一些 javascript 代码来动态重写目标 URL。 For this, you need to specify a javascript file instead of a json file as the --proxy-conf parameter in your 'start' script parameter list:为此,您需要在“开始”脚本参数列表中指定一个 javascript 文件而不是 json 文件作为 --proxy-conf 参数:

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

As shown above, the --base-href parameter also needs to be set to / if you otherwise set the <base href="..."> to a path in your index.html.如上所示,如果您将 <base href="..."> 设置为 index.html 中的路径,则还需要将 --base-href 参数设置为 /。 This setting will override that and it's necessary to make sure URLs in the http requests are correctly constructed.此设置将覆盖该设置,并且有必要确保正确构造 http 请求中的 URL。

Then you need the following or similar content in your proxy.conf.js (not json!):然后你需要在你的 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;

Note that the router option can be used in two ways.请注意,可以通过两种方式使用路由器选项。 One is when you assign an object containing key value pairs where the key is the requested host/path to match and the value is the rewritten target URL.一种是当您分配一个包含键值对的对象时,其中键是请求匹配的主机/路径,值是重写的目标 URL。 The other way is when you assign a function with some custom code, which is what I'm demonstrating in my examples here.另一种方法是当您使用一些自定义代码分配函数时,这就是我在此处的示例中演示的内容。 In the latter case I found that the target option still needs to be set to something in order for the router option to work.在后一种情况下,我发现目标选项仍然需要设置为某些东西才能使路由器选项工作。 If you assign a custom function to the router option then the target option is not used so it could be just set to true.如果您为路由器选项分配自定义功能,则不会使用目标选项,因此可以将其设置为 true。 Otherwise, it needs to be the default target URL.否则,它需要是默认的目标 URL。

Webpack uses http-proxy-middleware so you'll find useful documentation there: https://github.com/chimurai/http-proxy-middleware/blob/master/README.md#http-proxy-middleware-options Webpack 使用 http-proxy-middleware 所以你会在那里找到有用的文档: https : //github.com/chimurai/http-proxy-middleware/blob/master/README.md#http-proxy-middleware-options

The following example will get the developer name from a cookie to determine the target URL using a custom function as router:以下示例将从 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;

(The cookie is set for localhost and path '/' and with a long expiry using a browser plugin. If the cookie doesn't exist, the URL will point to the live site.) (cookie 是为 localhost 和路径 '/' 设置的,并且使用浏览器插件设置了很长时间。如果 cookie 不存在,则 URL 将指向实时站点。)

In case if someone is looking for multiple context entries to the same target or TypeScript based configuration.如果有人正在寻找同一目标或基于 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 ng serve --proxy-config=./proxy.conf.ts -o

We can find the proxy documentation for Angular-CLI over here:我们可以在这里找到 Angular-CLI 的代理文档:

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

After setting up a file called proxy.conf.json in your root folder, edit your package.json to include the proxy config on ng start.在根文件夹中设置名为 proxy.conf.json 的文件后,编辑 package.json 以在 ng start 时包含代理配置。 After adding "start": "ng serve --proxy-config proxy.conf.json" to your scripts, run npm start and not ng serve, because that will ignore the flag setup in your package.json.将 "start": "ng serve --proxy-config proxy.conf.json" 添加到脚本后,运行 npm start 而不是 ng serve,因为这将忽略 package.json 中的标志设置。

current version of angular-cli: 1.1.0 angular-cli 的当前版本:1.1.0

It's important to note that the proxy path will be appended to whatever you configured as your target.请务必注意,代理路径将附加到您配置为目标的任何内容。 So a configuration like this:所以像这样的配置:

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

and a request like http://localhost:4200/api will result in a call to http://myhost.com/api/api .并且像http://localhost:4200/api这样的请求将导致对http://myhost.com/api/api的调用。 I think the intent here is to not have two different paths between development and production environment.我认为这里的意图是在开发和生产环境之间没有两条不同的路径。 All you need to do is using /api as your base URL.您需要做的就是使用/api作为您的基本 URL。

So the correct way would be to simply use the part that comes before the api path, in this case just the host address:所以正确的方法是简单地使用 api 路径之前的部分,在这种情况下只是主机地址:

{
  "/api": {
    "target": "http://myhost.com",
    ...
  }
}
  1. add in proxy.conf.json, all request to /api will be redirect to htt://targetIP:targetPort/api.添加proxy.conf.json,所有对/api的请求都会重定向到htt://targetIP:targetPort/api。
{
  "/api": {
    "target": "http://targetIP:targetPort",
    "secure": false,
    "pathRewrite": {"^/api" : targeturl/api},
    "changeOrigin": true,
    "logLevel": "debug"
  }
}
  1. in package.json, make "start": "ng serve --proxy-config proxy.conf.json"在 package.json 中,使"start": "ng serve --proxy-config proxy.conf.json"

  2. in code let url = "/api/clnsIt/dev/78";在代码中让 url = "/api/clnsIt/dev/78"; this url will be translated to http://targetIP:targetPort/api/clnsIt/dev/78.这个 url 将被转换为 http://targetIP:targetPort/api/clnsIt/dev/78。

  3. You can also force rewrite by filling the pathRewrite.您还可以通过填充 pathRewrite 来强制重写。 This is the link for details cmd/NPM console will log something like "Rewriting path from "/api/..." to "http://targeturl:targetPort/api/..", while browser console will log "http://loclahost/api"这是详细信息的链接cmd/NPM 控制台将记录“重写路径从“/api/...”到“http://targeturl:targetPort/api/..”,而浏览器控制台将记录“http: //本地主机/api”

Step 1:Go to Your root folder Create proxy.conf.json第 1 步:转到您的根文件夹创建proxy.conf.json

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

Step 2:Go to package.json find "scripts" under that find "start"第 2 步:转到package.json中找到“start”下的“scripts”

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

Step 3:now add /auth/ in your http第 3 步:现在在您的http添加 /auth/

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

Step 4:Final Step in Terminal run npm start第 4 步:终端中的最后一步运行npm start

Here is another working example (@angular/cli 1.0.4):这是另一个工作示例(@angular/cli 1.0.4):

proxy.conf.json : proxy.conf.json :

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

run with :运行:

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

Cors-origin issue screenshot Cors-origin 问题截图

Cors issue has been faced in my application.我的应用程序中遇到了 Cors 问题。 refer above screenshot.参考上面的截图。 After adding proxy config issue has been resolved.添加代理配置问题后已解决。 my application url: localhost:4200 and requesting api url:" http://www.datasciencetoolkit.org/maps/api/geocode/json?sensor=false&address= "我的应用程序 url: localhost:4200 并请求 api url:" http://www.datasciencetoolkit.org/maps/api/geocode/json?sensor=false&address= "

Api side no-cors permission allowed.允许 Api 侧 no-cors 许可。 And also I'm not able to change cors-issue in server side and I had to change only in angular(client side).而且我无法在服务器端更改 cors 问题,我只能在 angular(客户端)中更改。

Steps to resolve:解决步骤:

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

Note: We have skip hostname name url in Api request, it will auto add while giving request.注意:我们在 Api 请求中跳过了主机名 url,它会在提供请求时自动添加。 whenever changing proxy.conf.js we have to restart ng-serve, then only changes will update.每当更改 proxy.conf.js 时,我们必须重新启动 ng-serve,然后只有更改才会更新。

  1. Config proxy in angular.json在 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" } } },

After finishing these step restart ng-serve Proxy working correctly as expect refer here完成这些步骤后,重新启动 ng-serve代理按预期正常工作,请参阅此处

> 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

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

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