Jak dodać żądanie CORS w nagłówku w Angular 5

87

Dodałem CORS w nagłówku, ale nadal otrzymuję problem z CORS w moim żądaniu. Jaki jest prawidłowy sposób dodawania i obsługi CORS i innych żądań w nagłówkach?

Oto kod pliku usługi:

import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
const httpOptions = {
  headers: new HttpHeaders({ 
    'Access-Control-Allow-Origin':'*',
    'Authorization':'authkey',
    'userid':'1'
  })
};

public baseurl = 'http://localhost/XXXXXX';

userAPI(data): Observable<any> {
  return this.http.post(this.baseurl, data, httpOptions)
    .pipe(
      tap((result) => console.log('result-->',result)),
      catchError(this.handleError('error', []))
    );
}

Błąd:

Odpowiedź na żądanie inspekcji wstępnej nie przechodzi kontroli dostępu: w żądanym zasobie nie ma nagłówka „Access-Control-Allow-Origin”. Dlatego źródło „ http: // localhost: 4200 ” nie ma dostępu

nie powiodło się: odpowiedź błędu HTTP dla (nieznany adres URL): 0 nieznany błąd

W moim kodzie po stronie serwera dodałem CORS w pliku indeksu.

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Aman Kumar
źródło
3
Trzeba dodać nagłówki Cors po stronie serwera.
Sachila Ranawaka
@SachilaRanawaka Tak, dodałem go do mojego pliku indeksu.
Aman Kumar
opublikuj ten plik serwera
Sachila Ranawaka
Ta odpowiedź może być przydatna: stackoverflow.com/a/58064366/7059557
AmirReza-Farahlagha

Odpowiedzi:

51

Z mojego doświadczenia wynika, że ​​wtyczki działały z HTTP, ale nie z najnowszym httpClient. Ponadto skonfigurowanie nagłówków odpowiedzi CORS na serwerze nie było tak naprawdę opcją. Utworzyłem więc proxy.conf.jsonplik, który ma działać jako serwer proxy.

Przeczytaj więcej na ten temat tutaj .

proxy.conf.json plik:

{
  "/posts": {
    "target": "https://example.com",
    "secure": true,
    "pathRewrite": {
    "^/posts": ""
  },
    "changeOrigin": true
  }
}

Umieściłem proxy.conf.jsonplik tuż obokpackage.json pliku w tym samym katalogu.

Następnie zmodyfikowałem polecenie start w pliku package.json:

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

Wywołanie HTTP z mojego komponentu aplikacji:

return this._http.get('/posts/pictures?method=GetPictures')
.subscribe((returnedStuff) => {
  console.log(returnedStuff);
});

Na koniec, aby uruchomić moją aplikację, musiałbym użyć npm startlubng serve --proxy-config proxy.conf.json

rgantla
źródło
15
Działa tylko do celów programistycznych. Nie możesz zbudować aplikacji za pomocą tego narzędzia proxy
GVArt,
Czy ktoś tutaj mógłby rzucić okiem na pytanie na stackoverflow.com/questions/55429787/ ...
Nelson King
co powinniśmy ustawić targetjak w pliku proxy.config?
A-Sharabiani
związałem go, pokazując stan ok, ale teraz pojawia się nowy błąd. HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:4200/", ok: false, …} error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) message: "Unexpected token < in JSON at position 0" "
Aman Gupta
8
to nie działa w kompilacjach produkcyjnych, więc nie może być właściwym rozwiązaniem
Aaron Matthews
4

Możesz także wypróbować fetchfunkcję i no-corstryb. Czasami jest to łatwiejsze do skonfigurowania niż wbudowany w Angular moduł http. Możesz kliknąć prawym przyciskiem myszy żądania na karcie sieciowej narzędzi deweloperskich Chrome i skopiować je w składni pobierania, co jest świetne.

import { from } from 'rxjs';

// ...

result = from( // wrap the fetch in a from if you need an rxjs Observable
  fetch(
    this.baseurl,
    {
      body: JSON.stringify(data)
      headers: {
        'Content-Type': 'application/json',
      },
      method: 'POST',
      mode: 'no-cors'
    }
  )
);
metakermit
źródło
Kod w pytaniu próbuje odczytać odpowiedź. no-corsblokuje to. Blokuje również ustawianie typu zawartości na application/json.
Quentin
Bardzo specyficzny przypadek, dla api.github.com/orgs/nesign/repos , widziałem, że Access to XMLHttpRequest at '..' from origin '..' has been blocked by CORS policy: Request header field x-timezone is not allowed by Access-Control-Allow-Headers in preflight response.nie można zastąpić, Access-Control-Request-Headers: cache-control,x-timezonektóry został dodany domyślnie :( i Github ma to w odpowiedzi Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Accept-Encoding, X-GitHub-OTP, X-Requested-With, User-Agentpobieranie zadziałało
Anand Rockzz
Ups! x-czasowa został dodany przeze mnie - miałem ponad inżynieriihttpclient z przechwytujących długi czas do tyłu :)
Anand Rockzz
3

Jeśli jesteś podobny do mnie i korzystasz z lokalnego serwera SMS Gateway i wykonujesz żądanie GET na adres IP taki jak 192.168.0.xx, na pewno otrzymasz błąd CORS.

Niestety nie mogłem znaleźć rozwiązania Angulara, ale z pomocą poprzedniej powtórki dostałem swoje rozwiązanie i zamieszczam zaktualizowaną wersję dla Angular 7 8 9

import {from} from 'rxjs';

getData(): Observable<any> {
    return from(
      fetch(
        'http://xxxxx', // the url you are trying to access
        {
          headers: {
            'Content-Type': 'application/json',
          },
          method: 'GET', // GET, POST, PUT, DELETE
          mode: 'no-cors' // the most important option
        }
      ));
  }

Po prostu zasubskrybuj jak zwykle.

Avram Virgil
źródło
2

Spraw, aby nagłówek wyglądał następująco dla HttpClient w NG5:

let httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'apikey': this.apikey,
        'appkey': this.appkey,
      }),
      params: new HttpParams().set('program_id', this.program_id)
    };

Będziesz mógł nawiązywać połączenia API z adresem URL swojego lokalnego hosta, to działa dla mnie.

  • Nigdy nie zapomnij kolumny parametrów w nagłówku: na przykład params: new HttpParams (). Set ('program_id', this.program_id)
Damon Wu
źródło
2

POST z httpClient w Angular 6 również wykonywał żądanie OPTIONS:

Nagłówki Ogólne:

URL żądania: https: //hp-probook/perl-bin/muziek.pl/=/postData
Metoda żądania: OPCJE
Kod stanu: 200 OK
Adres zdalny: 127.0.0.1: 443
Polityka odsyłająca: no-referrer-when-downgrade

Mój serwer Perl REST implementuje żądanie OPTIONS z kodem powrotu 200.

Następny nagłówek żądania POST:

Zaakceptować:*/*
Zaakceptuj kodowanie: gzip, deflate, br
Accept-Language: nl-NL, nl; q = 0,8, en-US; q = 0,6, en; q = 0,4
Access-Control-Request-Headers: typ zawartości
Metoda-żądania-kontroli-dostępu: POST
Połączenie: utrzymuj przy życiu
Host: hp-probook
Pochodzenie: http: // localhost: 4200
Referer: http: // localhost: 4200 /
User-Agent: Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit / 537.36 (KHTML, jak Gecko) Chrome / 59.0.3071.109 Safari / 537.36

Uwaga Access-Control-Request-Headers: content-type.

Tak więc mój skrypt backend w Perlu używa następujących nagłówków:

 - "Access-Control-Allow-Origin" => '*',
 - "Access-Control-Allow-Methods" => 'GET, POST, PATCH, DELETE, PUT, OPTIONS',
 - "Access-Control-Allow-Headers" => 'Origin, Content-Type, X-Auth-Token, content-type',

W tej konfiguracji GET i POST działały dla mnie!

Rob Lassche
źródło
1

proszę zaimportować requestoptions z kątowych cors

    import {RequestOptions, Request, Headers } from '@angular/http';

i dodaj opcje żądania w swoim kodzie, jak podano poniżej

    let requestOptions = new RequestOptions({ headers:null, withCredentials: 
    true });

opcja wysyłania żądania w żądaniu interfejsu API

fragment kodu poniżej

     let requestOptions = new RequestOptions({ headers:null, 
     withCredentials: true });
     return this.http.get(this.config.baseUrl + 
     this.config.getDropDownListForProject, requestOptions)
     .map(res => 
     {
      if(res != null)
      { 
        return res.json();
        //return true;
      }
    })
  .catch(this.handleError);
   }  

i dodaj CORS w kodzie PHP zaplecza, w którym wszystkie żądania API będą trafiać jako pierwsze.

spróbuj tego i daj mi znać, czy działa, czy nie. miałem ten sam problem. Dodawałem CORS z angular5, który nie działał, a następnie dodałem CORS do zaplecza i zadziałało dla mnie

raj yadav
źródło
-6

Poniższe zadziałały dla mnie po godzinach prób

      $http.post("http://localhost:8080/yourresource", parameter, {headers: 
      {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } }).

Jednak poniższy kod nie zadziałał, nie wiem dlaczego, mam nadzieję, że ktoś może poprawić tę odpowiedź.

          $http({   method: 'POST', url: "http://localhost:8080/yourresource", 
                    parameter, 
                    headers: {'Content-Type': 'application/json', 
                              'Access-Control-Allow-Origin': '*',
                              'Access-Control-Allow-Methods': 'POST'} 
                })
MG Developer
źródło
1
$ http? Czy to AngularJS, ponieważ mówimy tam o Angular 5. Nie mogłem sprawić, by ten kod zadziałał
Victor Jozwicki
@VictorJozwicki Masz rację, to nie jest Angular 5. W moim pliku package.json widać wersję kątową 1.7.5.
MG Developer