Angular——为每个请求设置头信息

我需要在用户登录后为每个后续请求设置一些授权头。


为特定请求设置头信息,

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

Reference .

但是,以这种方式为每个请求手动设置请求头是不可行的。

我如何设置头设置一旦用户登录,也删除注销这些头?

551915 次浏览

为了回答你的问题,你可以提供一个服务来包装Angular的原始Http对象。如下所述。

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
});
}
}

而不是注入Http对象,你可以注入这个对象(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 );
});
}
}

我还认为可以为Http类使用多个提供者,通过提供自己的类来扩展Http…参见这个链接:http://blog.thoughtram.io/angular2/2015/11/23/multi-providers-in-angular-2.html

在这种情况下,扩展BaseRequestOptions可能会有很大帮助。看看下面的代码:

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 })
]);

这应该包括'My-Custom-Header'在每个调用。

更新:

为了能够在任何时候改变头,而不是上面的代码,你也可以使用下面的代码来添加一个新的头:

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

要删除就可以了

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

还有另一个函数,你可以用来设置值:

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

上述解决方案在typescript上下文中仍然不完全有效。_defaultHeaders是受保护的,不应该这样使用。我会推荐上面的解决方案作为快速修复,但从长远来看,更好的方法是编写自己的包装器来处理http调用,它也可以处理身份验证。以auth0为例,它更好、更简洁。

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

更新- 2018年6月 我看到很多人选择这个解决方案,但我建议不要这么做。全局追加头将发送认证令牌每一个 api调用从你的应用程序。因此api调用到第三方插件,如对讲或zendesk或任何其他api也将携带你的授权头。这可能会导致一个很大的安全漏洞。 因此,取而代之的是,使用全局拦截器,但手动检查外部调用是否指向服务器的api端点,然后附加认证头

虽然我很晚才回,但也许能帮到别人。当使用@NgModule时,要向所有请求注入头文件,可以执行以下操作:

(我在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');
}
}

现在在@NgModule中执行以下操作:

@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]
})

像下面这样保持独立的服务怎么样

            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);
}
}

当你从另一个地方调用它时,使用this.httpClientService.addHeader("Authorization", "Bearer " + this.tok);

你会看到添加的头文件eg:- 授权,如下所示

enter image description here

你可以在你的路由中使用canActive,如下所示:

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]
}
];

取自:https://auth0.com/blog/angular-2-authentication

以下是已接受答案的改进版本,针对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());
}
}

当然,如果需要的话,它应该扩展为deleteput这样的方法(在我的项目中,目前还不需要它们)。

这样做的好处是在get/post/…方法。

注意,在我的例子中,我使用cookie进行身份验证。我需要i18n的报头(Accept-Language报头),因为我们的API返回的许多值都被翻译成用户的语言。在我的应用程序中,i18n服务保存用户当前选择的语言。

通过扩展Angular 2的Http Provider来创建一个自定义Http类,并简单地覆盖自定义Http类中的constructorrequest方法。下面的例子在每个http请求中添加Authorization头。

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);
};
}
}

然后配置你的主app.module.ts来提供XHRBackend作为ConnectionBackend提供者,并将RequestOptions提供给你的自定义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 ]
})

在此之后,现在可以在服务中使用自定义http提供程序。例如:

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();
} );
}
}

下面是一个全面的指南——http://adonespitogo.com/articles/angular-2-extending-http-provider/

Angular 2.1.2中,我通过扩展angular 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)
}
}

然后在我的应用程序提供者中,我可以使用自定义工厂来提供“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(){


}
}

现在我不需要声明每个Http方法,并且可以在整个应用程序中正常使用http

angular 2.0.1及更高版本有一些改动:

    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 { }
经过一些调查,我发现最后也是最简单的方法是扩展BaseRequestOptions,这是我更喜欢的 以下是我尝试过的方法,但由于某些原因我放弃了 1. 扩展BaseRequestOptions,并在constructor()中添加动态头文件。如果我登录,它不能工作。它只创建一次。所以它不是动态的
2. 延长Http。与上面的原因相同,我不能在constructor()中添加动态头文件。如果我重写request(..)方法,并设置头文件,像这样:

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));
}

你只需要重写这个方法,而不是重写所有的get/post/put方法。

3.我的首选解决方案是扩展BaseRequestOptions并覆盖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;
}
}

这个merge()函数将被每个请求调用。

虽然我回答这个问题很晚,但如果有人在寻求更简单的解决方案。

我们可以用angular -jwt。angular2-jwt在从Angular 2应用中发起HTTP请求时,会自动将一个JSON Web令牌(JWT)作为授权标头。

我们可以用高级配置选项设置全局标头

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);
}

发送每个请求令牌

    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')
);
}

迟到总比不到好……=)

你可以采用扩展BaseRequestOptions的概念(这里是https://angular.io/docs/ts/latest/guide/server-communication.html !# override-default-request-options)并“动态”刷新头文件(不仅仅是在构造函数中)。你可以像这样使用getter/setter重写“headers”属性:

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 };

我喜欢覆盖默认选项的想法,这似乎是一个很好的解决方案。

然而,如果你打算扩展Http类。一定要把这篇文章看完!

这里的一些答案实际上显示了request()方法的不正确重载,这可能导致难以捕捉的错误和奇怪的行为。这是我自己偶然发现的。

这个解决方案基于Angular 4.2.x中的request()方法实现,但应该与未来兼容:

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;


}


}

注意,我以import { Http as NgHttp } from '@angular/http';的方式导入原始类,以防止名称冲突。

这里要解决的问题是request()方法有两个不同的调用签名。当传递的是Request对象而不是URL string时,Angular会忽略options参数。所以这两种情况都必须妥善处理。

下面是如何用DI容器注册这个被重写的类的例子:

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
);
}

使用这种方法,你可以正常地注入Http类,但是你被重写的类会被神奇地注入。这允许您轻松地集成您的解决方案,而无需更改应用程序的其他部分(操作中的多态性)。

只需将httpProvider添加到模块元数据的providers属性中。

我已经能够选择一个更简单的解决方案>添加一个新的头到默认选项合并或加载你的api得到(或其他)函数。

get(endpoint: string, params?: any, options?: RequestOptions) {
if (!options) {
options = new RequestOptions();
options.headers = new Headers( { "Accept": "application/json" } ); <<<<
}
// [...]
}
当然,你可以在你的类的默认选项或任何东西中外部化这个头。 这是Ionic生成的api。ts @Injectable()导出类API {}

这是非常快的,它为我工作。我不想要json/ld格式。

HTTP拦截器是现在可用,通过新的HttpClient@angular/common/http从Angular 4.3开始。X版本及以上版本

现在为每个请求添加头文件非常简单:

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

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.append('Authorization', 'Bearer 123') });


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

有一个不变原则,这就是为什么在设置新内容之前需要克隆请求。

由于编辑头部是一个非常常见的任务,实际上有一个快捷方式(在克隆请求时):

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

在创建拦截器之后,你应该使用HTTP_INTERCEPTORS提供来注册它。

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


@NgModule({
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: AddHeaderInterceptor,
multi: true,
}],
})
export class AppModule {}

这就是我如何为每个请求设置令牌。

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;
}
}

并在app.module.ts中注册

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [
{ provide: RequestOptions, useClass: CustomRequestOptions }
],
bootstrap: [AppComponent]
})
export class AppModule { }

最简单的

创建一个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
})
}
}

然后在你的service上,导入config.ts文件

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;
})
);
}

我认为这是最简单和最安全的。

对于Angular 5及以上版本,我们可以使用HttpInterceptor泛化请求和响应操作。 这有助于我们避免重复:

1)通用报头

2)指定响应类型

3)查询请求

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
}
});
}
}

我们可以使用这个AuthHttpInterceptor类作为HttpInterceptors的提供者:

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 {
}

你可以用一些授权头创建你自己的http客户端:

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


@Injectable({
providedIn: 'root'
})
export class HttpClientWithAuthorization {


constructor(private http: HttpClient) {}


createAuthorizationHeader(bearerToken: string): HttpHeaders {
const headerDict = {
Authorization: 'Bearer ' + bearerToken,
}
return new HttpHeaders(headerDict);
}


get<T>(url, bearerToken) {
this.createAuthorizationHeader(bearerToken);
return this.http.get<T>(url, {
headers: this.createAuthorizationHeader(bearerToken)
});
}


post<T>(url, bearerToken, data) {
this.createAuthorizationHeader(bearerToken);
return this.http.post<T>(url, data, {
headers: this.createAuthorizationHeader(bearerToken)
});
}
}

然后在你的服务类中注入它而不是HttpClient:

@Injectable({
providedIn: 'root'
})
export class SomeService {


constructor(readonly httpClientWithAuthorization: HttpClientWithAuthorization) {}


getSomething(): Observable<Object> {
return this.httpClientWithAuthorization.get<Object>(url,'someBearer');
}


postSomething(data) {
return this.httpClientWithAuthorization.post<Object>(url,'someBearer', data);
}
}

您可以使用拦截器,而不是为每个请求一次又一次地设置报头。

每个发出的请求都会经过拦截器,在拦截器中你可以设置你的认证头,然后释放请求。

HTTP拦截器是实现这一点的正确方法。在这里没有看到关于如何完全实现它的适当文档,所以我包含了谷歌官方指南的链接。在实现之前,我已经通读了文档,因为在安全性和使用多个拦截器包方面存在许多潜在的缺陷。

< a href = " https://angular。Io /guide/http# intercepter -requests-and-responses" rel="nofollow noreferrer">https://angular.io/guide/http#intercepting-requests-and-responses

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


import { Observable } from 'rxjs';


/** Pass untouched request through to the next request handler. */
@Injectable()
export class NoopInterceptor implements HttpInterceptor {


intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
return next.handle(req);
}
}

我设置头的最大问题(在2022年)是HttpHeaders上的append方法返回原始对象的克隆,而没有修改原始对象本身。所以headers.append('header', 'value')是不够的。我必须重新分配结果或直接在HTTP调用中使用它:

let headers = new HttpHeaders();
headers = headers.append('header', 'value');
this.http.get<any>('https://someulr.com/api/users', { headers });
const headers = new HttpHeaders()
.set('content-type', 'application/json')
.set('x-functions-key', '');


return this.http.get<Person[]>(baseUrl, {
headers: headers,
});

使用append方法将新值附加到现有值集

headers.append('Access-Control-Allow-Origin', '*')