我在documentation找不到为所有http请求设置基本API网址的方法。是否可以使用Angular HttpClient?
答案 0 :(得分:63)
使用新的HttpClient Interceptor。
创建一个实现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);
}
}
的正确注射剂:
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: APIInterceptor,
multi: true,
}
]
HttpInterceptor可以克隆请求并根据需要进行更改,在这种情况下,我为所有http请求定义了默认路径。
为HttpClientModule提供以下配置:
your-api-url/
现在,您的所有请求都将以||
答案 1 :(得分:16)
基于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: "..."
};
答案 2 :(得分:5)
您不一定需要基本网址与 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`);
}
}
答案 3 :(得分:1)
我认为没有默认方法可以做到这一点。做HttpService并在里面你可以定义你的默认URL的属性,并使用你的属性URL调用http.get和其他人的方法。然后注入HttpService而不是HttpClient
答案 4 :(得分: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;
}
答案 5 :(得分:0)
为什么不创建一个具有可配置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);
}
}
答案 6 :(得分:0)
每个关注阿列克谢的人都回答了,但不能像我一样让它工作 - 这是因为您还必须将这个元素添加到提供者数组中
{
provide: HTTP_INTERCEPTORS,
useClass: BaseUrlInterceptor,
multi: true
}
不幸的是,我的声誉太低,无法在他的回答中添加评论。