Angular 4服务中如何复用公共请求头?
在Angular 4中复用公共HTTP请求头的方案
我来帮你解决这个问题!在Angular 4里,你可以通过两种常用方式来避免重复编写公共请求头,同时还能灵活传入不同的secret-apikey,下面给你详细说明:
方案一:封装基础API服务(兼容所有Angular 4版本)
这种方式适合所有Angular 4版本,尤其是4.3以下(因为Angular 4.3才引入HttpClient和拦截器)。核心思路是创建一个基础服务,把公共请求头的逻辑封装进去,然后其他业务服务都依赖这个基础服务来发起请求。
1. 创建基础服务文件 base-api.service.ts
import { Injectable } from '@angular/core'; import { Http, Headers, RequestOptions, Response } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/toPromise'; import 'rxjs/add/operator/catch'; @Injectable() export class BaseApiService { // 定义公共请求头 private readonly commonHeaders = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/json', // 这里可以添加其他所有请求都需要的公共头 }); constructor(private http: Http) {} // 封装GET请求,允许传入自定义的secret-apikey get(url: string, secretKey: string): Promise<any> { // 复制公共头创建新实例,避免修改原有的公共头(重要!) const requestHeaders = new Headers(this.commonHeaders); requestHeaders.append('secret-apikey', secretKey); const options = new RequestOptions({ headers: requestHeaders }); return this.http.get(url, options) .toPromise() .then((response: Response) => response.json()) .catch(this.handleError); } // 封装POST请求,同理可扩展PUT、DELETE等 post(url: string, body: any, secretKey: string): Promise<any> { const requestHeaders = new Headers(this.commonHeaders); requestHeaders.append('secret-apikey', secretKey); const options = new RequestOptions({ headers: requestHeaders }); return this.http.post(url, body, options) .toPromise() .then((response: Response) => response.json()) .catch(this.handleError); } // 统一处理错误 private handleError(error: any): Promise<any> { console.error('请求出错:', error); return Promise.reject(error.message || error); } }
2. 在业务服务中使用基础服务
比如创建一个用户服务 user.service.ts,只需要传入对应的secret-apikey即可:
import { Injectable } from '@angular/core'; import { BaseApiService } from './base-api.service'; @Injectable() export class UserService { private readonly apiBaseUrl = 'https://your-api-domain.com/users'; // 当前业务模块的专属secret-apikey private readonly userSecretKey = 'USER_SECRET_12345'; constructor(private baseApi: BaseApiService) {} // 获取用户列表 getUsers(): Promise<any> { return this.baseApi.get(this.apiBaseUrl, this.userSecretKey); } // 创建新用户 createUser(userData: any): Promise<any> { return this.baseApi.post(`${this.apiBaseUrl}/create`, userData, this.userSecretKey); } }
方案二:使用HTTP拦截器(仅Angular 4.3+适用)
如果你的项目是Angular 4.3及以上版本,推荐使用HttpClient的拦截器功能,它能自动拦截所有HTTP请求,统一添加公共头,同时支持动态传入不同的secret-apikey。
1. 创建拦截器文件 api-header.interceptor.ts
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; @Injectable() export class ApiHeaderInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 第一步:添加公共请求头 let modifiedRequest = request.clone({ setHeaders: { 'Content-Type': 'application/json', 'Accept': 'application/json' // 其他公共头 } }); // 第二步:从请求参数中获取secret-apikey并添加到请求头 // 发起请求时我们将secretKey放在params里,这里取出后移除(避免传给后端) const secretKey = request.params.get('secretKey'); if (secretKey) { modifiedRequest = modifiedRequest.clone({ setHeaders: { 'secret-apikey': secretKey }, params: request.params.delete('secretKey') }); } return next.handle(modifiedRequest); } }
2. 在根模块中注册拦截器
修改app.module.ts,注册拦截器并导入HttpClientModule:
import { NgModule } from '@angular/core'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { ApiHeaderInterceptor } from './api-header.interceptor'; @NgModule({ imports: [HttpClientModule], // 必须导入这个模块 providers: [ { provide: HTTP_INTERCEPTORS, useClass: ApiHeaderInterceptor, multi: true // 允许多个拦截器并存 } ] }) export class AppModule {}
3. 在业务服务中发起请求
比如创建商品服务 product.service.ts,只需要在请求参数中传入secretKey即可:
import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; @Injectable() export class ProductService { private readonly apiBaseUrl = 'https://your-api-domain.com/products'; private readonly productSecretKey = 'PRODUCT_SECRET_67890'; constructor(private http: HttpClient) {} // 获取商品列表 getProducts() { const params = new HttpParams().set('secretKey', this.productSecretKey); return this.http.get(this.apiBaseUrl, { params }); } // 创建商品 createProduct(productData: any) { const params = new HttpParams().set('secretKey', this.productSecretKey); return this.http.post(`${this.apiBaseUrl}/create`, productData, { params }); } }
注意事项
- 方案一中,一定要复制公共头创建新的Headers实例,否则多次请求会导致
secret-apikey被重复添加到同一个Headers对象中。 - 方案二中,确保你的Angular版本是4.3及以上,因为
HttpClient和拦截器是这个版本才引入的。
内容的提问来源于stack exchange,提问作者jay4116
相关产品推荐
相关产品推荐

