19

when I import HttpClient to call my own written node.js API, there are some issues with the settings of the URL.

for example:

import { HttpClient, HttpHeaders } from '@angular/common/http';

export class myComponent implements OnInit {

    constructor(
    private http: HttpClient,
    ) {}

    ngOnInit(): void {
       this.http.get('http://127.0.0.1:3000/getData/theme').subscribe(data => {

       });
    });
}

//angular default port 4200,
//node.js default port 3000,

when I set this.http.get('/getData/theme') the get will be call http://127.0.0.1:4200, this is wrong. if I set this.http.get('http://127.0.0.1:3000/getData/theme') for local development it works. but, when ng build setting to actual server, it can't connect properly.

the console:

GET http://127.0.0.1:3000/getData/theme 
net::ERR_CONNECTION_REFUSED

GET http://localhost:3000/structureData/themeData 
net::ERR_CONNECTION_REFUSED

How can I set the correct URL to allow it to meet both online and local development status?


angular-cli server - how to proxy API requests to another server?

I set the package.json:

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

and

proxy.conf.json
{
  "/api": {
    "target": "http://localhost:3000",
    "secure": false
  }
}

it's not working:

this.http.get('/getData/theme')

GET http://localhost:4200/getData/theme 404 (Not Found)

or

this.http.get('/api/getData/theme')

GET http://localhost:4200/api/getData/theme 404 (Not Found)
Finn
  • 1,323
  • 5
  • 24
  • 46
  • Possible duplicate of [angular-cli server - how to proxy API requests to another server?](https://stackoverflow.com/questions/37172928/angular-cli-server-how-to-proxy-api-requests-to-another-server) – Igor Mar 12 '18 at 16:15
  • See the proposed duplicate question. If you are using the cli you can use the proxy configuration which will route to the host (*server and port can be configured*) of your choice. – Igor Mar 12 '18 at 16:15
  • 2
    @Igor The proxy configuration is intended to proxy calls when running the dev server via ng serve. After you run ng build you are responsible for the web server and its configurations. – Vikas Mar 12 '18 at 16:23
  • it's not working, I will modify in my question. – Finn Mar 12 '18 at 16:39
  • Share your endpoint, does it have a mapping for '/api'? – Vikas Mar 12 '18 at 16:58
  • 4
    `"/api"` is a pattern. Any URL starting with `/api` is routed through the proxy. `/getData` does not start with `/api`. If you wanted to make a catch all you could use an empty string. – Igor Mar 12 '18 at 17:24
  • I tried two ways to add /api or not, routers do not lead to the correct location (3000) – Finn Mar 13 '18 at 01:49
  • This whole "proxy file" thing is complete BS and IMO shows how Angular is slowly sliding itself right into the garbage can... – Jim Nov 02 '21 at 16:04

4 Answers4

29

I think that happens because you missed the changeOrigin attribute.

Note: proxy.config.json files only work in your local environment, these are configurations for the angular-cli server.

I made different proxy.config.json files for local and production (when locally I make a request from the browser, it will be redirected to production). I use pathRewrite to rewrite the requested url, so if I request http://localhost:4200/client-api/stores it will redirect to https://www.your-web.com/api/stores

proxy-prod.config.json

"/client-api/*": {
    "target": "https://www.your-web.com/api",
    "pathRewrite": { "^/client-api": "" },
    "secure": false,
    "changeOrigin": true,
    "logLevel": "debug"
  }

proxy-local.config.json

"/client-api/*": {
    "target": "http://localhost:22222",
    "pathRewrite": { "^/client-api": "" },
    "secure": false,
    "changeOrigin": true,
    "logLevel": "debug"
  }

In the angular.json file I use the proxy config files inside the serving configurations.

angular.json

...
       "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "app:build",
            "proxyConfig": "src/proxy-local.conf.json"
          },
          "configurations": {
            "production": {
              "browserTarget": "app:build:production",
              "proxyConfig": "src/proxy-prod.conf.json"
            },
          }
        },
...

If you run ng serve, the application will use the local proxy. Use ng serve --prod for production.

adrisons
  • 3,443
  • 3
  • 32
  • 48
  • Thanks @adrisons, how do you build this for a production deployment? In the case when I have CORS in my ajax(GET) call how do I substitute the url? How do I pass parameters in proxy.config.json file? – David Sagang Sep 23 '20 at 19:05
  • 1
    Hello @DavidSagang, this proxy.config.json only works in development because angular server uses it. CORS errors happen when in the browser you receive data from a different url than the one your app is served. The easier way to fix CORS errors is to make the HTTP call from your server, and make your web app request it from your server. – adrisons Sep 24 '20 at 07:10
  • 2
    this is for ng serve --prod question was about ng build – Lenzman Mar 06 '21 at 14:12
  • @adrisons You wrote that it only works for development but you have a `proxy-prod` file. I have 3 environments: `localhost, staging and production` and I created for each one a proxy file, is it ok? – Offir Jun 28 '22 at 06:58
  • I'll update my answer to clarify, but this is all happening in your local environment. I use the `proxy-prod` file to rewrite the requested url to the production one, but these proxy.config.json files will ONLY WORK LOCALLY – adrisons Jun 28 '22 at 08:05
  • @adrisons it works fine for me in `staging` and I think it will work fine in `production` as well. I host my application in `IIS`. take a look at the question I posted: https://stackoverflow.com/questions/72782387/using-angular-proxy-for-multiple-environments – Offir Jun 28 '22 at 08:13
  • @Offir The angular reverse proxy (and the entire angular web server) is implemented using the "webpack dev server". It doesn't have the level of security, stability or performance quality required for production. It uses a ton of memory and it probably won't scale with tons of requests (it's simply not built for that). – adrisons Jun 28 '22 at 08:18
  • @adrisons I think you don't understand exactly my situation, I have a windows server with `IIS` as a reverse proxy. In the same server I host my `Angular application` so I just use it to redirect the api requests to my `IIS` server instead of using a `baseUrl` property. – Offir Jun 28 '22 at 08:22
  • @adrisons so every request such as `api/get-data` is redirected to other domain ,in my `staging` server all the requests will be redirected to `staging.mydomain.com/api.get-data`, in production server all `mydomain.com/api.get-data` – Offir Jun 28 '22 at 08:24
  • @Offir Yes, it can work for small projects, but if this is a profesional environment you should not use Angular's dev server – adrisons Jun 28 '22 at 08:29
  • @adrisons So how do you call to an api from your Angular application, do you use something like `baseUrl`? – Offir Jun 28 '22 at 08:48
  • You should generate your application bundle and serve it from a web server. From your app you can send requests to that server using url `/` (without domain) – adrisons Jun 28 '22 at 10:39
  • @adrisons I decided to go with `baseUrl` interceptor instead of proxy, based on your advice it seems like to right thing to do. https://stackoverflow.com/questions/45735655/how-do-i-set-the-baseurl-for-angular-httpclient – Offir Jun 28 '22 at 10:40
  • 1
    @Offir it'd be great if you marked my answers as helpful :) – adrisons Jun 29 '22 at 09:02
12

I had the same problem... To serve my front into production I use Nginx. If you have the same scenario, you can do this:

location /api {
       rewrite /api/(.*) /$1  break;
       proxy_pass http://exempleApi.com
}

This equals in your proxy.config.json that you use in the development:

  {
    "/api/*": {
      "target": "http://exempleApi.com",
      "secure": false,
      "logLevel": "debug",
      "changeOrigin": "true",
      "pathRewrite": {"^/api": ""}
    }
  }
Diego Silva
  • 121
  • 1
  • 3
2

I use this proxy.conf.json

 {
    "/Api/Workflow/Preview/*": {
        "target": "https://subdomain.domain.com/",
        "protocol": "https:",
        "secure": false,
        "changeOrigin": true
    }
}

i belive that you must to write this proxy.conf.json:

{
  "/api/*": {
    "target": "http://localhost:3000",
    "secure": false,
    "changeOrigin": true
  }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Luiggi
  • 358
  • 4
  • 12
1

Sometimes we want to use the Ng production deployment file and don't want the Ng server to run, so we only need to use the Angular output(dist).

The proxy options on our web server can be set up to act as a proxy server when we have a local development environment. Nginx needs to be added to the Dockerfile and a proxy options file was added to the Dockerfile. Dockerfile uses a simple copy command to set up a proxy.

production.nginx.proxy.conf

server {   listen 80;   listen [::]:80;   server_name localhost;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm; 
    try_files $uri $uri/ /index.html =404;
}

  location /identity {
    proxy_pass http://yourapi.com; }

  location /someroute{
    proxy_pass http://yourapi.com:5021; } 
}

Dockerfile

FROM node:18-alpine as build
WORKDIR /usr/local/app
COPY ./ /usr/local/app/
COPY package*.json ./
RUN npm install -g npm@latest
RUN npm install --force
RUN npm run build --prod

FROM nginx:1.21.6
# ---- We set our proxy configuration in the following line ----
COPY production.nginx.proxy.conf /etc/nginx/conf.d/default.conf
COPY --from=build /usr/local/app/dist/your-project-name /usr/share/nginx/html

EXPOSE 80
Shervin Ivari
  • 1,759
  • 5
  • 20
  • 28