Как установить baseUrl для углового HttpClient?

Я не нашел способ в документации, чтобы установить URL базы API для HTTP - запросов. Возможно ли это сделать с помощью Angular HttpClient?

Ответы

Ответ 1

Используйте новый HttpClient Interceptor.

Создайте правильную инъекцию, которая реализует 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-запросов.

Предоставить HttpClientModule следующие конфигурации:

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

Теперь все ваши запросы начинаются с your-api-url/

Ответ 2

Основываясь на очень полезном ответе TheUnreal, можно написать перехватчик, чтобы получить базовый URL через DI:

@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: "..."
}; 

Ответ 3

вам необязательно нужен базовый URL с HttpClient, документы говорят, что вам просто нужно указать часть 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`);
  }

}

Ответ 4

Выдержки из Visual Studio 2017 asp.net.

включить ниже строки в 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;
}

Ответ 5

Я думаю, что для этого нет способа по умолчанию. У HttpService и внутри вы можете определить свойство вашего URL-адреса по умолчанию и сделать методы для вызова http.get и других с вашим URL-адресом свойств. Затем введите HttpService вместо HttpClient

Ответ 6

Почему бы не создать подкласс HttpClient с настраиваемым baseUrl? Таким образом, если вашему приложению необходимо взаимодействовать с несколькими службами, вы можете использовать разные подклассы для каждого или создать несколько экземпляров одного подкласса, каждый из которых имеет свою конфигурацию.

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