Kątowe-ustawiane nagłówki na każde żądanie

Muszę ustawić nagłówki autoryzacji po zalogowaniu się użytkownika, dla każdego kolejnego żądania.


Aby ustawić nagłówki dla konkretnego żądania,

import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);

// HTTP POST using these headers
this.http.post(url, data, {
  headers: headers
})
// do something with the response

Odniesienie

Nie byłoby jednak możliwe ręczne ustawianie nagłówków żądań dla każdego żądania w ten sposób.

Jak ustawić nagłówki ustawione po zalogowaniu się użytkownika, a także usunąć te nagłówki po wylogowaniu?

 249
Author: RobC, 2015-12-25

18 answers

Aby odpowiedzieć na pytanie, możesz dostarczyć usługę, która zawija oryginalny Http obiekt z Angular. Coś takiego jak opisane poniżej.

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';

@Injectable()
export class HttpClient {

  constructor(private http: Http) {}

  createAuthorizationHeader(headers: Headers) {
    headers.append('Authorization', 'Basic ' +
      btoa('username:password')); 
  }

  get(url) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.get(url, {
      headers: headers
    });
  }

  post(url, data) {
    let headers = new Headers();
    this.createAuthorizationHeader(headers);
    return this.http.post(url, data, {
      headers: headers
    });
  }
}

I zamiast wstrzykiwać obiekt Http można wstrzyknąć ten (HttpClient).

import { HttpClient } from './http-client';

export class MyComponent {
  // Notice we inject "our" HttpClient here, naming it Http so it's easier
  constructor(http: HttpClient) {
    this.http = httpClient;
  }

  handleSomething() {
    this.http.post(url, data).subscribe(result => {
        // console.log( result );
    });
  }
}

Myślę również, że coś można zrobić używając wielu dostawców dla klasy Http, dostarczając własną klasę rozszerzającą Http... Zobacz ten link: http://blog.thoughtram.io/angular2/2015/11/23/multi-providers-in-angular-2.html .

 325
Author: Thierry Templier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 08:31:15

Http interceptors are now available via the new HttpClient od @angular/common/http, od 4.3.wersje x i dalej .

Dodanie nagłówka dla każdego żądania jest teraz bardzo proste:

import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
} from '@angular/common/http';

export class AddHeaderInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Clone the request to add the new header
    const clonedRequest = req.clone({ headers: req.headers.set('Authorization', 'Bearer 123') });

    // Pass the cloned request instead of the original request to the next handle
    return next.handle(clonedRequest);
  }
}

Istnieje zasada niezmienności , dlatego żądanie musi zostać sklonowane przed ustawieniem na nim czegoś nowego.

Ponieważ edycja nagłówków jest bardzo częstym zadaniem, istnieje skrót do niego (podczas klonowania wniosek):

const clonedRequest = req.clone({ setHeaders: { Authorization: 'Bearer 123' } });

Po utworzeniu Interceptora należy go zarejestrować za pomocą HTTP_INTERCEPTORS provide.

import { HTTP_INTERCEPTORS } from '@angular/common/http';

@NgModule({
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: AddHeaderInterceptor,
    multi: true,
  }],
})
export class AppModule {}
 82
Author: Edmundo Rodrigues,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-28 20:54:21

Rozszerzenie BaseRequestOptions może być bardzo pomocne w tym scenariuszu. Sprawdź następujący kod:

import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS, Headers, Http, BaseRequestOptions} from 'angular2/http';

import {AppCmp} from './components/app/app';


class MyRequestOptions extends BaseRequestOptions {
  constructor () {
    super();
    this.headers.append('My-Custom-Header','MyCustomHeaderValue');
  }
} 

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(RequestOptions, { useClass: MyRequestOptions })
]);

To powinno zawierać 'My-Custom-Header' w każdym wywołaniu.

Update:

Aby móc zmienić nagłówek w dowolnym momencie, zamiast powyższego kodu, Możesz również użyć następującego kodu, aby dodać nowy nagłówek:

this.http._defaultOptions.headers.append('Authorization', 'token');

Aby usunąć możesz zrobić

this.http._defaultOptions.headers.delete('Authorization');

Istnieje również inna funkcja, której możesz użyć do ustawienia wartości:

this.http._defaultOptions.headers.set('Authorization', 'token');

Powyższe rozwiązanie nadal jest nie do końca poprawne w kontekście maszynopisu. _defaultHeaders jest chroniony i nie powinien być używany w ten sposób. Polecam powyższe rozwiązanie do szybkiej naprawy, ale na dłuższą metę lepiej jest napisać własne opakowanie wokół połączeń http, które również obsługuje auth. Weźmy przykład z auth0, który jest lepszy i czysty.

Https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts

Aktualizacja-Czerwiec 2018 Widzę, że wielu ludzi idzie na to rozwiązanie, ale radziłbym inaczej. Dołączanie nagłówka globalnie wyśle Token auth do każdego wywołania api wychodzącego z Twojej aplikacji. Tak więc połączenia api przechodzące do wtyczek innych firm, takich jak intercom lub zendesk lub jakikolwiek inny api, będą również zawierać nagłówek autoryzacji. Może to spowodować dużą wadę bezpieczeństwa. Zamiast tego użyj interceptor globalnie, ale sprawdź ręcznie, czy połączenie wychodzące jest skierowane do punktu końcowego api serwera, a następnie załącz nagłówek auth.

 76
Author: anit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-05 10:16:14

Chociaż odpowiem bardzo późno, ale to może pomóc komuś innemu. Aby wstawić nagłówki do wszystkich żądań, gdy używane jest @NgModule, można wykonać następujące czynności:

(testowałem to w Angular 2.0.1)

/**
 * Extending BaseRequestOptions to inject common headers to all requests.
 */
class CustomRequestOptions extends BaseRequestOptions {
    constructor() {
        super();
        this.headers.append('Authorization', 'my-token');
        this.headers.append('foo', 'bar');
    }
}

Teraz w @NgModule wykonaj następujące czynności:

@NgModule({
    declarations: [FooComponent],
    imports     : [

        // Angular modules
        BrowserModule,
        HttpModule,         // This is required

        /* other modules */
    ],
    providers   : [
        {provide: LocationStrategy, useClass: HashLocationStrategy},
        // This is the main part. We are telling Angular to provide an instance of
        // CustomRequestOptions whenever someone injects RequestOptions
        {provide: RequestOptions, useClass: CustomRequestOptions}
    ],
    bootstrap   : [AppComponent]
})
 24
Author: Shashank Agrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 05:38:48

W {[2] } podszedłem do tego rozszerzając kątowy Http:

import {Injectable} from "@angular/core";
import {Http, Headers, RequestOptionsArgs, Request, Response, ConnectionBackend, RequestOptions} from "@angular/http";
import {Observable} from 'rxjs/Observable';

@Injectable()
export class HttpClient extends Http {

  constructor(protected _backend: ConnectionBackend, protected _defaultOptions: RequestOptions) {

    super(_backend, _defaultOptions);
  }

  _setCustomHeaders(options?: RequestOptionsArgs):RequestOptionsArgs{
    if(!options) {
      options = new RequestOptions({});
    }
    if(localStorage.getItem("id_token")) {

      if (!options.headers) {

        options.headers = new Headers();


      }
      options.headers.set("Authorization", localStorage.getItem("id_token"))
    }
    return options;
  }


  request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);
    return super.request(url, options)
  }
}
Następnie w moich dostawców aplikacji udało mi się użyć niestandardowej fabryki, aby zapewnić "Http"
import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';
import { RequestOptions, Http, XHRBackend} from '@angular/http';
import {HttpClient} from './httpClient';//above snippet

function httpClientFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
  return new HttpClient(xhrBackend, requestOptions);
}

@NgModule({
  imports:[
    FormsModule,
    BrowserModule,
  ],
  declarations: APP_DECLARATIONS,
  bootstrap:[AppComponent],
  providers:[
     { provide: Http, useFactory: httpClientFactory, deps: [XHRBackend, RequestOptions]}
  ],
})
export class AppModule {
  constructor(){

  }
}

Teraz nie muszę deklarować każdej metody Http i mogę normalnie używać http w całej mojej aplikacji.

 15
Author: jonnie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-01 14:20:34

Utwórz niestandardową klasę Http, rozszerzając dostawcę Angular 2 Http i po prostu nadpisuj metodę constructor i request w niestandardowej klasie Http. Poniższy przykład dodaje nagłówek Authorization do każdego żądania http.

import {Injectable} from '@angular/core';
import {Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class HttpService extends Http {

  constructor (backend: XHRBackend, options: RequestOptions) {
    let token = localStorage.getItem('auth_token'); // your custom token getter function here
    options.headers.set('Authorization', `Bearer ${token}`);
    super(backend, options);
  }

  request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    let token = localStorage.getItem('auth_token');
    if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
      if (!options) {
        // let's make option object
        options = {headers: new Headers()};
      }
      options.headers.set('Authorization', `Bearer ${token}`);
    } else {
    // we have to add the token to the url object
      url.headers.set('Authorization', `Bearer ${token}`);
    }
    return super.request(url, options).catch(this.catchAuthError(this));
  }

  private catchAuthError (self: HttpService) {
    // we have to pass HttpService's own instance here as `self`
    return (res: Response) => {
      console.log(res);
      if (res.status === 401 || res.status === 403) {
        // if not authenticated
        console.log(res);
      }
      return Observable.throw(res);
    };
  }
}

Następnie skonfiguruj swoją główną app.module.ts, aby zapewnić XHRBackend jako dostawca ConnectionBackend i RequestOptions do niestandardowej klasy Http:

import { HttpModule, RequestOptions, XHRBackend } from '@angular/http';
import { HttpService } from './services/http.service';
...
@NgModule({
  imports: [..],
  providers: [
    {
      provide: HttpService,
      useFactory: (backend: XHRBackend, options: RequestOptions) => {
        return new HttpService(backend, options);
      },
      deps: [XHRBackend, RequestOptions]
    }
  ],
  bootstrap: [ AppComponent ]
})

Po tym, można teraz korzystać z niestandardowego dostawcy http w swoich usługach. Na przykład:

import { Injectable }     from '@angular/core';
import {HttpService} from './http.service';

@Injectable()
class UserService {
  constructor (private http: HttpService) {}

  // token will added automatically to get request header
  getUser (id: number) {
    return this.http.get(`/users/${id}`).map((res) => {
      return res.json();
    } );
  }
}

Oto obszerny przewodnik - http://adonespitogo.com/articles/angular-2-extending-http-provider/

 12
Author: Adones Pitogo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-07 03:04:05

Lepiej późno niż wcale... =)

Możesz wziąć pojęcie rozszerzone BaseRequestOptions (stąd https://angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options) i odświeżać nagłówki "w locie" (nie tylko w konstruktorze). Możesz użyć właściwości Getter / setter "headers" w następujący sposób:

import { Injectable } from '@angular/core';
import { BaseRequestOptions, RequestOptions, Headers } from '@angular/http';

@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions {

    private superHeaders: Headers;

    get headers() {
        // Set the default 'Content-Type' header
        this.superHeaders.set('Content-Type', 'application/json');

        const token = localStorage.getItem('authToken');
        if(token) {
            this.superHeaders.set('Authorization', `Bearer ${token}`);
        } else {
            this.superHeaders.delete('Authorization');
        }
        return this.superHeaders;
    }

    set headers(headers: Headers) {
        this.superHeaders = headers;
    }

    constructor() {
        super();
    }
}

export const requestOptionsProvider = { provide: RequestOptions, useClass: DefaultRequestOptions };
 8
Author: Александр Ильинский,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-15 13:41:48

Oto ulepszona wersja zaakceptowanej odpowiedzi, zaktualizowana do Angular2 final:

import {Injectable} from "@angular/core";
import {Http, Headers, Response, Request, BaseRequestOptions, RequestMethod} from "@angular/http";
import {I18nService} from "../lang-picker/i18n.service";
import {Observable} from "rxjs";
@Injectable()
export class HttpClient {

    constructor(private http: Http, private i18n: I18nService ) {}

    get(url:string):Observable<Response> {
        return this.request(url, RequestMethod.Get);
    }

    post(url:string, body:any) {   
        return this.request(url, RequestMethod.Post, body);
    }

    private request(url:string, method:RequestMethod, body?:any):Observable<Response>{

        let headers = new Headers();
        this.createAcceptLanguageHeader(headers);

        let options = new BaseRequestOptions();
        options.headers = headers;
        options.url = url;
        options.method = method;
        options.body = body;
        options.withCredentials = true;

        let request = new Request(options);

        return this.http.request(request);
    }

    // set the accept-language header using the value from i18n service that holds the language currently selected by the user
    private createAcceptLanguageHeader(headers:Headers) {

        headers.append('Accept-Language', this.i18n.getCurrentLang());
    }
}

Oczywiście powinna być rozszerzona o metody takie jak delete i put w razie potrzeby(nie potrzebuję ich jeszcze w tym momencie w moim projekcie).

Zaletą jest to, że wget/post/... metody.

Zauważ, że w moim przypadku używam plików cookie do uwierzytelniania. Potrzebowałem nagłówka dla i18n (nagłówek Accept-Language), ponieważ wiele wartości zwracanych przez nasze API jest tłumaczonych w języku użytkownika. W mojej aplikacji usługa i18n posiada język aktualnie wybrany przez użytkownika.

 6
Author: Pierre Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-01 15:37:09

Jak o utrzymanie oddzielnego serwisu jak następuje

            import {Injectable} from '@angular/core';
            import {Headers, Http, RequestOptions} from '@angular/http';


            @Injectable()
            export class HttpClientService extends RequestOptions {

                constructor(private requestOptionArgs:RequestOptions) {
                    super();     
                }

                addHeader(headerName: string, headerValue: string ){
                    (this.requestOptionArgs.headers as Headers).set(headerName, headerValue);
                }
            }

A gdy wywołujesz to z innego miejsca użyj this.httpClientService.addHeader("Authorization", "Bearer " + this.tok);

I zobaczysz dodany nagłówek np: - w następujący sposób

Tutaj wpisz opis obrazka

 5
Author: Kalanamith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-07 05:03:04

Po pewnym dochodzeniu, znalazłem ostateczny i najprostszy sposób jest rozszerzenie BaseRequestOptions, który wolę.
Oto sposoby, które próbowałem i z jakiegoś powodu się poddałem:
1. rozszerz BaseRequestOptions i dodaj dynamiczne nagłówki w constructor(). To nie może działać, jeśli się zaloguję. Zostanie utworzony raz. Więc nie jest dynamiczny.
2. extend Http. Z tego samego powodu, co powyżej, nie mogę dodać dynamicznych nagłówków w constructor(). A jeśli przepisuję metodę request(..) i ustawiam nagłówki, tak:

request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
 let token = localStorage.getItem(AppConstants.tokenName);
 if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
  if (!options) {
    options = new RequestOptions({});
  }
  options.headers.set('Authorization', 'token_value');
 } else {
  url.headers.set('Authorization', 'token_value');
 }
 return super.request(url, options).catch(this.catchAuthError(this));
}

Wystarczy, że zastąp tę metodę, ale nie wszystkie metody get / post/put.

3.A moim preferowanym rozwiązaniem jest extend BaseRequestOptions i overwrite merge():

@Injectable()
export class AuthRequestOptions extends BaseRequestOptions {

 merge(options?: RequestOptionsArgs): RequestOptions {
  var newOptions = super.merge(options);
  let token = localStorage.getItem(AppConstants.tokenName);
  newOptions.headers.set(AppConstants.authHeaderName, token);
  return newOptions;
 }
}

Ta merge() funkcja zostanie wywołana dla każdego żądania.

 5
Author: Mavlarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 07:15:37

Chociaż odpowiem na to bardzo późno, ale jeśli ktoś szuka łatwiejszego rozwiązania.

Możemy użyć angular2-jwt. angular2-jwt jest przydatny automatycznie dołączając JSON Web Token (JWT) jako nagłówek autoryzacji podczas wykonywania żądań HTTP z aplikacji Angular 2.

Możemy ustawić nagłówki globalne z opcją advanced configuration

export function authHttpServiceFactory(http: Http, options: RequestOptions) {
  return new AuthHttp(new AuthConfig({
    tokenName: 'token',
        tokenGetter: (() => sessionStorage.getItem('token')),
        globalHeaders: [{'Content-Type':'application/json'}],
    }), http, options);
}

I wysyłanie na żądanie tokena jak

    getThing() {
  let myHeader = new Headers();
  myHeader.append('Content-Type', 'application/json');

  this.authHttp.get('http://example.com/api/thing', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );

  // Pass it after the body in a POST request
  this.authHttp.post('http://example.com/api/thing', 'post body', { headers: myHeader })
    .subscribe(
      data => this.thing = data,
      err => console.log(error),
      () => console.log('Request Complete')
    );
}
 5
Author: KNimhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-14 07:37:33

Tak zrobiłem ustawiając token przy każdym żądaniu.

import { RequestOptions, BaseRequestOptions, RequestOptionsArgs } from '@angular/http';

export class CustomRequestOptions extends BaseRequestOptions {

    constructor() {
        super();
        this.headers.set('Content-Type', 'application/json');
    }
    merge(options?: RequestOptionsArgs): RequestOptions {
        const token = localStorage.getItem('token');
        const newOptions = super.merge(options);
        if (token) {
            newOptions.headers.set('Authorization', `Bearer ${token}`);
        }

        return newOptions;
    }
}

I zarejestrować się w aplikacji.moduł.ts

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule
    ],
    providers: [
        { provide: RequestOptions, useClass: CustomRequestOptions }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
 5
Author: Rajkeshwar Prasad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 09:14:45

Podoba mi się pomysł zastąpienia domyślnych opcji, to wydaje się dobrym rozwiązaniem.

Jednakże, jeśli jesteś gotowy do rozszerzenia klasy Http. Koniecznie przeczytaj to!

Niektóre odpowiedzi tutaj pokazują nieprawidłowe przeciążenie metody request(), co może prowadzić do trudnych do złapania błędów i dziwnego zachowania. Sam na to wpadłem.

Rozwiązanie to opiera się na implementacji metody request() w Angular 4.2.x, ale powinno być kompatybilność z przyszłością:

import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';

import {
  ConnectionBackend, Headers,
  Http as NgHttp,
  Request,
  RequestOptions,
  RequestOptionsArgs,
  Response,
  XHRBackend
} from '@angular/http';


import {AuthenticationStateService} from '../authentication/authentication-state.service';


@Injectable()
export class Http extends NgHttp {

  constructor (
    backend: ConnectionBackend,
    defaultOptions: RequestOptions,
    private authenticationStateService: AuthenticationStateService
  ) {
    super(backend, defaultOptions);
  }


  request (url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

    if ('string' === typeof url) {

      url = this.rewriteUrl(url);
      options = (options || new RequestOptions());
      options.headers = this.updateHeaders(options.headers);

      return super.request(url, options);

    } else if (url instanceof Request) {

      const request = url;
      request.url = this.rewriteUrl(request.url);
      request.headers = this.updateHeaders(request.headers);

      return super.request(request);

    } else {
      throw new Error('First argument must be a url string or Request instance');
    }

  }


  private rewriteUrl (url: string) {
    return environment.backendBaseUrl + url;
  }

  private updateHeaders (headers?: Headers) {

    headers = headers || new Headers();

    // Authenticating the request.
    if (this.authenticationStateService.isAuthenticated() && !headers.has('Authorization')) {
      headers.append('Authorization', 'Bearer ' + this.authenticationStateService.getToken());
    }

    return headers;

  }

}

Zauważ, że importuję oryginalną klasę w ten sposób import { Http as NgHttp } from '@angular/http';, aby zapobiec konfliktom nazw.

Problem polega na tym, że metoda request() ma dwa różne sygnatury wywołania. Gdy obiekt Request jest przekazywany zamiast adresu URL string, argument options jest ignorowany przez Angular. Więc obie sprawy muszą być odpowiednio rozpatrzone.

A oto przykład jak zarejestrować tę nadpisaną klasę z DI pojemnik:

export const httpProvider = {
  provide: NgHttp,
  useFactory: httpFactory,
  deps: [XHRBackend, RequestOptions, AuthenticationStateService]
};


export function httpFactory (
  xhrBackend: XHRBackend,
  requestOptions: RequestOptions,
  authenticationStateService: AuthenticationStateService
): Http {
  return new Http(
    xhrBackend,
    requestOptions,
    authenticationStateService
  );
}

Przy takim podejściu możesz normalnie wstrzyknąć Http klasę, ale zamiast tego twoja nadpisana Klasa zostanie magicznie wstrzyknięta. Pozwala to na łatwą integrację rozwiązania bez zmiany innych części aplikacji (polimorfizm w działaniu).

Wystarczy dodać httpProvider do właściwości providers metadanych modułu.

 4
Author: Slava Fomin II,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-14 18:57:08

Dla Angular 5 i wyżej, możemy użyć HttpInterceptor do uogólnienia operacji żądania i odpowiedzi. To pomaga nam uniknąć powielania:

1) Wspólne nagłówki

2) Określanie typu odpowiedzi

3) zapytanie ofertowe

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {

  requestCounter: number = 0;
  constructor() {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    request = request.clone({
      responseType: 'json',
      setHeaders: {
        Authorization: `Bearer token_value`,
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    });

    return next.handle(request).do((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        // do stuff with response if you want
      }
    }, (err: any) => {
      if (err instanceof HttpErrorResponse) {
        // do stuff with response error if you want
      }
    });
  }
}

Możemy użyć tej klasy AuthHttpInterceptor jako dostawcy dla Httpinterceptorów:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing-module';
import { AuthHttpInterceptor } from './services/auth-http.interceptor';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthHttpInterceptor,
      multi: true
    }
  ],
  exports: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}
 1
Author: Prachi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 09:29:56

Były pewne zmiany dla angular 2.0.1 i wyższych:

    import {RequestOptions, RequestMethod, Headers} from '@angular/http';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpModule }     from '@angular/http';
    import { AppRoutingModule } from './app.routing.module';   
    import { AppComponent }  from './app.component';

    //you can move this class to a better place
    class GlobalHttpOptions extends RequestOptions {
        constructor() { 
          super({ 
            method: RequestMethod.Get,
            headers: new Headers({
              'MyHeader': 'MyHeaderValue',
            })
          });
        }
      }

    @NgModule({

      imports:      [ BrowserModule, HttpModule, AppRoutingModule ],
      declarations: [ AppComponent],
      bootstrap:    [ AppComponent ],
      providers:    [ { provide: RequestOptions, useClass: GlobalHttpOptions} ]
    })

    export class AppModule { }
 0
Author: Carlos Casallas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-06 17:25:45

Mam możliwość wyboru prostszego rozwiązania > Dodaj nowe nagłówki do domyślnych opcji Scalaj lub ładuj za pomocą funkcji get (lub innej) API.

get(endpoint: string, params?: any, options?: RequestOptions) {
  if (!options) {
    options = new RequestOptions();
    options.headers = new Headers( { "Accept": "application/json" } ); <<<<
  }
  // [...] 
}

Oczywiście możesz uzewnętrznić te nagłówki w domyślnych opcjach lub cokolwiek w swojej klasie. Jest to w Ionic generated api.ts @Injectable () export class API {}

Jest bardzo szybki i działa na mnie. Nie chciałem formatu json/ld.
 0
Author: Paul Leclerc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-18 19:14:07

Najprostszy ze wszystkich

Utwórz plik config.ts

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

export class Config {
    url: string = 'http://localhost:3000';
    httpOptions: any = {
        headers: new HttpHeaders({
           'Content-Type': 'application/json',
           'Authorization': JSON.parse(localStorage.getItem('currentUser')).token
        })
    }
}

Następnie na service, po prostu zaimportuj config.ts Plik

import { Config } from '../config';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class OrganizationService {
  config = new Config;

  constructor(
    private http: HttpClient
  ) { }

  addData(data): Observable<any> {
     let sendAddLink = `${this.config.url}/api/addData`;

     return this.http.post(sendAddLink , data, this.config.httpOptions).pipe(
       tap(snap => {
      return snap;
        })
    );
 } 
Myślę, że był najprostszy i najbezpieczniejszy.
 0
Author: Joshua Fabillar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 05:04:42

Możesz używać canActive w swoich trasach, TAK:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: AuthService, private router: Router) {}

  canActivate() {
    // If user is not logged in we'll send them to the homepage 
    if (!this.auth.loggedIn()) {
      this.router.navigate(['']);
      return false;
    }
    return true;
  }

}

const appRoutes: Routes = [
  {
    path: '', redirectTo: '/deals', pathMatch: 'full'
  },
  {
    path: 'special',
    component: PrivateDealsComponent,
    /* We'll use the canActivate API and pass in our AuthGuard.
       Now any time the /special route is hit, the AuthGuard will run
       first to make sure the user is logged in before activating and
       loading this route. */
    canActivate: [AuthGuard]
  }
];

Pochodzi z: https://auth0.com/blog/angular-2-authentication

 -4
Author: A T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 16:02:57