首页 文章

如何为Angular HttpClient设置baseUrl?

提问于
浏览
38

我没有在documentation中找到为所有http请求设置基本API网址的方法 . 是否可以使用Angular HttpClient?

6 回答

  • 1

    使用新的HttpClient拦截器 .

    Create a proper injectable that implements HttpInterceptor:

    import {Injectable} from '@angular/core';
    import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
    import {Observable} from 'rxjs/Observable';
    
    @Injectable()
    export class APIInterceptor implements HttpInterceptor {
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        const apiReq = req.clone({ url: `your-api-url/${req.url}` });
        return next.handle(apiReq);
      }
    }
    

    HttpInterceptor可以克隆请求并根据需要进行更改,在这种情况下,我为所有http请求定义了一个默认路径 .

    Provide the HttpClientModule with the following configurations:

    providers: [{
          provide: HTTP_INTERCEPTORS,
          useClass: APIInterceptor,
          multi: true,
        }
      ]
    

    现在您的所有请求都将以 your-api-url/ 开头

  • 5

    根据 TheUnreal 非常有用的答案,可以编写拦截器以通过DI获取基本URL:

    @Injectable()
    export class BaseUrlInterceptor implements HttpInterceptor {
    
        constructor(
            @Inject('BASE_API_URL') private baseUrl: string) {
        }
    
        intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
            const apiReq = request.clone({ url: `${this.baseUrl}/${request.url}` });
            return next.handle(apiReq);
        }
    }
    

    BASE_API_URL 可以由应用程序模块提供:

    providers: [
        { provide: "BASE_API_URL", useValue: environment.apiUrl }
    ]
    

    其中 environment 是CLI在生成项目时自动创建的对象:

    export const environment = {
      production: false,
      apiUrl: "..."
    };
    
  • 12

    你不一定需要一个带有HttpClient的 base URL ,文档说你只需要指定请求的api部分,如果你正在调用同一个服务器它就像这样直截了当:

    this.http.get('/api/items').subscribe(data => { ...

    但是,您可以根据需要或指定基本URL .

    我有2条建议:

    1 . 具有静态类属性的辅助类 .

    export class HttpClientHelper{
    
        static baseURL: string = 'http://localhost:8080/myApp';
    }
    
    
    this.http.get(`${HttpClientHelper.baseURL}/api/items`);//in your service class
    

    2 . 具有类属性的基类,因此任何新服务都应该扩展它:

    export class BackendBaseService {
    
      baseURL: string = 'http://localhost:8080/myApp';
    
      constructor(){}
    

    }

    @Injectable()
    export class ItemsService extends BackendBaseService{
    
      constructor(private http: HttpClient){  
        super();
      }
    
      public listAll(): Observable<any>{    
        return this.http.get(`${this.baseURL}/api/items`);
      }
    
    }
    
  • 57

    我认为没有默认的方法来做到这一点 . 做HttpService并在里面你可以定义你的默认URL的属性,并使用你的属性URL调用http.get和其他人的方法 . 然后注入HttpService而不是HttpClient

  • 1

    为什么不创建一个具有可配置baseUrl的HttpClient子类?这样,如果您的应用程序需要与多个服务通信,您可以为每个服务使用不同的子类,或者创建单个子类的多个实例,每个子类具有不同的配置 .

    @Injectable()
    export class ApiHttpClient extends HttpClient {
      public baseUrl: string;
    
      public constructor(handler: HttpHandler) {
        super(handler);
    
        // Get base url from wherever you like, or provision ApiHttpClient in your AppComponent or some other high level
        // component and set the baseUrl there.
        this.baseUrl = '/api/';
      }
    
      public get(url: string, options?: Object): Observable<any> {
        url = this.baseUrl + url;
        return super.get(url, options);
      }
    }
    
  • 1

    摘自Visual Studio 2017 asp.net核心webapi角度示例应用程序 .

    包括Main.ts中的以下行

    export function getBaseUrl() {
      return document.getElementsByTagName('base')[0].href;
    }
    
    const providers = [
      { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
    ];
    

    在您的组件中

    constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
        http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
          this.forecasts = result;
        }, error => console.error(error));
      }
    

    我的完整main.ts代码如下所示

    import { enableProdMode } from '@angular/core';
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    
    import { AppModule } from './app/app.module';
    import { environment } from './environments/environment';
    
    export function getBaseUrl() {
      return document.getElementsByTagName('base')[0].href;
    }
    
    const providers = [
      { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
    ];
    
    if (environment.production) {
      enableProdMode();
    }
    
    platformBrowserDynamic()
      .bootstrapModule(AppModule)
      .catch(err => console.error(err));
    

    我的组件代码如下所示

    import { Component, Inject } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    @Component({
      selector: 'fetch-weather',
      templateUrl: './weather.component.html',
      styleUrls: ['./weather.component.scss']
    })
    
    export class WeatherComponent {
      public forecasts: WeatherForecast[];
    
      constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
        http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
          this.forecasts = result;
        }, error => console.error(error));
      }
    }
    
    interface WeatherForecast {
      dateFormatted: string;
      temperatureC: number;
      temperatureF: number;
      summary: string;
    }
    

相关问题