serwer angular-cli - jak proxy żądania API na inny serwer?

86

Z angular-cli ng servelokalnym serwerem deweloperskim obsługuje wszystkie pliki statyczne z katalogu mojego projektu.

Jak mogę przekierować moje wywołania AJAX na inny serwer?

elwyn
źródło

Odpowiedzi:

168

UPDATE 2017

Dostępna jest teraz lepsza dokumentacja i możesz używać konfiguracji opartych na JSON i JavaScript: proxy dokumentacji angular-cli

przykładowa konfiguracja serwera proxy https

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

O ile wiem, w wydaniu Angular 2.0 konfigurowanie serwerów proxy przy użyciu pliku .ember-cli nie jest zalecane. oficjalny sposób jest jak poniżej

  1. edytuj "start"swoje, package.jsonaby spojrzeć poniżej

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

  2. utwórz nowy plik o nazwie proxy.conf.jsonw katalogu głównym projektu i wewnątrz niego zdefiniuj swoje proxy, jak poniżej

    {
      "/api": {
        "target": "http://api.yourdomai.com",
        "secure": false
      }
    }
    
  3. Ważną rzeczą jest to, że używasz npm startzamiastng serve

Przeczytaj więcej tutaj: Konfiguracja proxy Angular 2 cli

imal hasaranga perera
źródło
1
Jak postępować z „niebezpiecznymi” poświadczeniami. Używając węzła, mogę ustawić process.env.NODE_TLS_REJECT_UNAUTHORIZED na 0 i ominie to zabezpieczenie, ale nie wiem, jak to zrobić z proxy.config.json. To wszystko jest stos rozwoju, nie mam nic przeciwko, jeśli czuję się niepewnie
nicowernli
1
posiadanie „secure”: false powinno wystarczyć, powinno to być wartość logiczna, a nie ciąg ... spędziłem niezliczoną ilość czasu, utrzymując to jako „false”
imal hasaranga perera
To działa dla mnie, ale z proxy kończy się to jak /api/api/personkażdy pomysł, dlaczego tak się dzieje?
ocespedes
czy możesz udostępnić swój plik proxy.conf.json, abym mógł rzucić okiem?
imal hasaranga perera
2
gdzie jest dokumentacja dotycząca proxy.conf.json?
odbyło się
44

Wyjaśnię, co musisz wiedzieć na poniższym przykładzie:

{
  "/folder/sub-folder/*": {
    "target": "http://localhost:1100",
    "secure": false,
    "pathRewrite": {
      "^/folder/sub-folder/": "/new-folder/"
    },
    "changeOrigin": true,
    "logLevel": "debug"
  }
}
  1. / folder / podfolder / * : ścieżka mówi: Kiedy widzę tę ścieżkę w mojej aplikacji kątowej (ścieżkę można przechowywać w dowolnym miejscu) chcę coś z nią zrobić. Znak * oznacza, że ​​będzie uwzględnione wszystko, co następuje po podfolderze. Na przykład, jeśli masz wiele czcionek w / folder / podfolder / , * wybierze je wszystkie

  2. "target" : " http: // localhost: 1100 " dla powyższej ścieżki uczyń docelowy adres URL hostem / źródłem, dlatego w tle będziemy mieli http: // localhost: 1100 / folder / podfolder /

  3. "pathRewrite ": {"^ / ​​folder / sub-folder /": "/ new-folder /"}, Teraz powiedzmy, że chcesz przetestować swoją aplikację lokalnie, adres http: // localhost: 1100 / folder / sub- folder / może zawiera nieprawidłową ścieżkę: / folder / podfolder /. Chcesz zmienić tę ścieżkę na poprawną ścieżkę, która jest http: // localhost: 1100 / new-folder / , dlatego pathRewrite stanie się bardzo przydatna. Wykluczy ścieżkę w aplikacji (lewa strona) i uwzględni nowo napisaną (prawa strona)

  4. „bezpieczny” : oznacza, czy używamy protokołu http czy https. Jeśli w atrybucie docelowym używany jest protokół https, ustaw atrybut secure na true, w przeciwnym razie ustaw go na false

  5. "changeOrigin" : opcja jest potrzebna tylko wtedy, gdy hostem docelowym nie jest bieżące środowisko, na przykład: localhost. Jeśli chcesz zmienić hosta na www.something.com, który byłby celem w proxy, ustaw atrybut changeOrigin na „true”:

  6. "logLevel" : atrybut określa, czy programista chce wyprowadzić proxy na swój terminal / cmd, dlatego użyje wartości "debug", jak pokazano na obrazku

Ogólnie proxy pomaga w tworzeniu aplikacji lokalnie. Ustawiasz ścieżki plików do celów produkcyjnych i jeśli masz wszystkie te pliki lokalnie w swoim projekcie, możesz po prostu użyć proxy, aby uzyskać do nich dostęp bez dynamicznej zmiany ścieżki w aplikacji.

Jeśli to działa, powinieneś zobaczyć coś takiego w swoim cmd / terminalu.

wprowadź opis obrazu tutaj

Eugen Sunic
źródło
1
Dzięki, to jest właściwa odpowiedź dla aktualnej wersji Angular. Opcja "changeOrigin" jest jednak konieczna tylko wtedy, gdy celem nie jest localhost . Musisz także załadować plik konfiguracyjny proxy, uruchamiając flagę, ng serv --proxy-config proxy.conf.json Najwyraźniej ignoruje flagę wewnątrz package.json (jak w poprzednich przykładach).
Andrew,
28

To było blisko pracy dla mnie. Musiałem również dodać:

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

Pełne proxy.conf.jsonpokazane poniżej:

{
    "/proxy/*": {
        "target": "https://url.com",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug",
        "pathRewrite": {
            "^/proxy": ""
        }
    }
}
Tony Scialo
źródło
10

EDYCJA: TO JUŻ NIE DZIAŁA W BIEŻĄCYM KĄTOWYM CLI

Zobacz odpowiedź od @imal hasaranga perera, aby uzyskać aktualne rozwiązanie


Serwer angular-clipochodzi z ember-cliprojektu. Aby skonfigurować serwer, utwórz .ember-cliplik w katalogu głównym projektu. Dodaj tam swoją konfigurację JSON:

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

Zrestartuj serwer, a będzie on proxy wszystkich żądań.

Na przykład wysyłam względne żądania w moim kodzie do /v1/foo/123, który jest odbierany pod adresem https://api.example.com/v1/foo/123.

Możesz także użyć flagi podczas uruchamiania serwera: ng serve --proxy https://api.example.com

Aktualny dla wersji angular-cli: 1.0.0-beta.0

elwyn
źródło
1
Dzięki za odpowiedź @elwyn. Czy możliwe jest proxy tylko dla adresów URL pasujących do jakiegoś wzorca, na przykład „/ api / v1 /”?
Marian Zagoruiko
Nie jestem pewien - nie miałem takiej potrzeby. Serwer sieciowy jest po prostu waniliowy ember-clipod maską (przynajmniej na razie), więc może zajrzyj do ich dokumentów? Wygląda na to, że ta osoba ma przykład uruchomionych niestandardowych serwerów proxy: stackoverflow.com/q/30267849/227622
elwyn
Zrobiłem to wczoraj. Jak powiedziałeś, to tylko waniliowy ember-cli. Stworzyłem więc aplikację ember, wygenerowałem tam proxy (nie ma jeszcze takiego generatora w angular-cli) i skopiowałem do mojej aplikacji angular. Działa dobrze. Dzięki.
Marian Zagoruiko
6

Oto inny sposób proxy, gdy potrzebujesz większej elastyczności:

Możesz użyć opcji „router” i trochę kodu javascript, aby dynamicznie przepisać docelowy adres URL. W tym celu musisz określić plik javascript zamiast pliku json jako parametr --proxy-conf na liście parametrów skryptu „start”:

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

Jak pokazano powyżej, parametr --base-href również musi być ustawiony na /, jeśli w innym przypadku ustawisz <base href = "..."> na ścieżkę w pliku index.html. To ustawienie zastąpi to i konieczne jest upewnienie się, że adresy URL w żądaniach http są poprawnie utworzone.

Następnie potrzebujesz następującej lub podobnej zawartości w swoim proxy.conf.js (nie 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;

Zwróć uwagę, że opcji routera można używać na dwa sposoby. Pierwsza polega na przypisaniu obiektu zawierającego pary klucz-wartość, gdzie klucz jest żądanym hostem / ścieżką do dopasowania, a wartością jest przepisany docelowy adres URL. Innym sposobem jest przypisanie funkcji za pomocą niestandardowego kodu, co demonstruję w moich przykładach tutaj. W tym drugim przypadku stwierdziłem, że opcja docelowa nadal musi być ustawiona na coś, aby opcja routera działała. Jeśli przypiszesz funkcję niestandardową do opcji routera, opcja docelowa nie będzie używana, więc może być po prostu ustawiona na wartość true. W przeciwnym razie musi to być domyślny docelowy adres URL.

Webpack wykorzystuje oprogramowanie pośredniczące http-proxy, więc znajdziesz tam przydatną dokumentację: https://github.com/chimurai/http-proxy-middleware/blob/master/README.md#http-proxy-middleware-options

Poniższy przykład pobierze nazwę programisty z pliku cookie, aby określić docelowy adres URL za pomocą niestandardowej funkcji routera:

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;

(Plik cookie jest ustawiony na localhost i ścieżkę „/” oraz z długim okresem ważności przy użyciu wtyczki przeglądarki. Jeśli plik cookie nie istnieje, adres URL będzie wskazywał aktywną witrynę).

Zoltan M.
źródło
3

Dokumentację proxy dla Angular-CLI możemy znaleźć tutaj:

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

Po skonfigurowaniu pliku o nazwie proxy.conf.json w folderze głównym, edytuj plik package.json, aby uwzględnić konfigurację serwera proxy przy uruchomieniu ng. Po dodaniu "start": "ng serv --proxy-config proxy.conf.json" do skryptów, uruchom polecenie npm start, a nie ng serv, ponieważ spowoduje to zignorowanie ustawienia flagi w pliku package.json.

aktualna wersja angular-cli: 1.1.0

Luuk Schoenmakers
źródło
3

Należy pamiętać, że ścieżka proxy zostanie dołączona do wszystkiego, co skonfigurujesz jako cel. Tak więc konfiguracja taka:

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

a żądanie takie jak http://localhost:4200/apispowoduje wezwanie do http://myhost.com/api/api. Myślę, że celem jest nie mieć dwóch różnych ścieżek między środowiskiem programistycznym a produkcyjnym. Wszystko, co musisz zrobić, to użyć /apijako podstawowego adresu URL.

Tak więc poprawnym sposobem byłoby po prostu użycie części znajdującej się przed ścieżką interfejsu API, w tym przypadku tylko adresu hosta:

{
  "/api": {
    "target": "http://myhost.com",
    ...
  }
}
codemusings
źródło
2

Krok 1: Przejdź do folderu głównego Utwórz proxy.conf.json

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

Krok 2: Przejdź do pliku package.json i znajdź „skrypty” pod pozycją „start”

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

Krok 3: teraz dodaj / auth / w swoim http

 return this.http
      .post('/auth/register/', { "username": 'simolee12', "email": '[email protected]', "password": 'Anything@Anything' });
  }

Krok 4: Ostatni krok w Terminal run npm start

yash sanghavi
źródło
2

W przypadku, gdy ktoś szuka wielu wpisów kontekstu do tego samego celu lub konfiguracji opartej na języku 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 służyć --proxy-config =. / proxy.conf.ts -o

prabhatojha
źródło
1

Oto kolejny działający przykład (@ 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"
  }
}

Biegnij z :

ng serve --proxy-config proxy.conf.json
Patrice
źródło
1

Zrzut ekranu z wydania Cors-origin

W mojej aplikacji wystąpił problem z Corsą. patrz powyższy zrzut ekranu. Po dodaniu konfiguracji proxy został rozwiązany. adres URL mojej aplikacji: localhost: 4200 i adres URL żądania interfejsu API: „ http://www.datasciencetoolkit.org/maps/api/geocode/json?sensor=false&address=

Zezwolenie no-cors po stronie API jest dozwolone. A także nie jestem w stanie zmienić problemu z corsami po stronie serwera i musiałem zmienić tylko w kątowym (po stronie klienta).

Kroki do rozwiązania:

  1. utwórz plik proxy.conf.json w folderze src.
   {
      "/maps/*": {
        "target": "http://www.datasciencetoolkit.org",
        "secure": false,
        "logLevel": "debug",
        "changeOrigin": true
      }
    }
  1. W żądaniu API
this.http
      .get<GeoCode>('maps/api/geocode/json?sensor=false&address=' + cityName)
      .pipe(
        tap(cityResponse => this.responseCache.set(cityName, cityResponse))
      );

Uwaga: pominęliśmy adres URL nazwy hosta w żądaniu API, zostanie on automatycznie dodany podczas wysyłania żądania. przy każdej zmianie proxy.conf.js musimy zrestartować ng-serv, wtedy tylko zmiany zostaną zaktualizowane.

  1. Konfiguracja proxy w 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"
            }
          }
        },

Po zakończeniu tego kroku uruchom ponownie ng-serv Proxy działające zgodnie z oczekiwaniami. Zobacz tutaj

> 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
dineshk033
źródło
0
  1. dodaj proxy.conf.json

    { "/api": { "target": "http://targetIP:9080", "secure": false, "pathRewrite": {"^/proxy" : ""}, "changeOrigin": true, "logLevel": "debug" } }

    1. w package.json, make "start": "ng serve --proxy-config proxy.conf.json"

    2. w kodzie niech url = "/ api / clnsIt / dev / 78"; ten adres URL zostanie przetłumaczony na http: // targetIP: 9080 / api / clnsIt / dev / 78

Feng Zhang
źródło