Angular httpClient headers

2019-08-30 18:38发布

问题:

Below is my HTTP post request to get the auth token, the headers are not getting set, in chrome I don't see the headers under request headers.

What I also observed is, if I add only the content-type header I can see the header and body being sent in the request, if I add authorization header then no header or body being sent in the request and I see Response to preflight has invalid HTTP status code 401. error on console.

I also tried enabling "CORS" still the same issue.

have tried all the commented options.

let headers = new HttpHeaders({ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'authorization': 'Basic ' + btoa("infoarchive.custom:mysecret") });

//headers  = headers.append("content-type","application/x-www-form-urlencoded");
//headers  = headers.append("authorization","Basic " + btoa("infoarchive.custom:mysecret"));
//headers = headers.set("Access-Control-Expose-Headers", "Authorization")
//headers = headers.set(Content-Type', 'application/x-www-form-urlencoded')
//headers = headers.set('Authorization', 'Basic aW5mb2FyY2hpdmUuY3VzdG9tOm15c2VjcmV0');      
console.log(headers)
const body = JSON.stringify({
    client_id: 'infoarchive.custom',
    username: userName,
    password: password,
    grant_type: 'password',
    scope: 'search'
});
return this.http.post('http://localhost:8080/oauth/token', body, { headers: headers })
    .map(
    (response: Response) => {
        const data = response.json();
        console.log("data:" + data)
        //  this.saveJwt(data.json().id_token);             
    }
    )
    .catch(
    (error: Response) => {
        console.log(error.status)
        return Observable.throw('Something went wrong');
    }
    );

回答1:

What you should do is use HttpInterceptor for this purpose and once this is configured it will automatically add information to your header for every http request and you will not have to manually add headers for every http request.

Following is an example of how I am getting a user object from the storage and using its authentication_token and sending it as a part of a header.

I hope this helps.

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {Observable} from "rxjs";
import { Storage } from "@ionic/storage";
import "rxjs/add/operator/mergeMap";

@Injectable()
export class AuthInterceptorProvider implements HttpInterceptor {
  constructor(private storage: Storage) {
    console.log("Hello AuthInterceptorProvider Provider");
  }

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

    return this.getUser().mergeMap(user => {
      if (user) {
        // clone and modify the request
        request = request.clone({
          setHeaders: {
            Authorization: `Bearer ${user.authentication_token}`
          }
        });
      }

      return next.handle(request);
    });
  }

  getUser(): Observable<any> {
    return Observable.fromPromise(this.storage.get("user"));
  }
}

I will also recommend you to read this article as this will give you more insight on this.



回答2:

Here is an example of how I have setup my http.service.ts with HttpClient. This works flawlessly for me and I can see my headers being set accordingly.

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

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { RequestOptions } from '../models/http.models';

@Injectable()
export class HttpService {
  domain: string = 'https://example-production.systems/';
  options: RequestOptions = {
    withCredentials: true,
    headers: new HttpHeaders({ 'X-CSRFToken': 'example-token' }),
  };

  constructor(
    public httpClient: HttpClient,
  ) {}

  post = (path: string, payload: any, query?: string): Observable<any> =>
    this.httpClient.post(`${this.domain}/${path}/${query}`, payload, this.options)
}

If you're curios - my RequestOptions interface looks like this:

export interface RequestOptions {
  headers: HttpHeaders;
  withCredentials: boolean;
}

I built this interface off of the list of accepted HTTPClient options can be found on the various HTTPClient client.d.ts methods. For example - accepted .post() options are as follows:

post(url: string, body: any | null, options?: {
    headers?: HttpHeaders | {
        [header: string]: string | string[];
    };
    observe?: 'body';
    params?: HttpParams | {
        [param: string]: string | string[];
    };
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<Object>;