在angularjs中,我们有http拦截器
$httpProvider.interceptors.push('myHttpInterceptor');
我们可以挂钩到所有http调用,并显示或隐藏加载条,进行日志记录等。
angular2中的等价物是什么?
答案 0 :(得分:63)
正如@Günter指出的那样,没有办法注册拦截器。您需要扩展Http
类并将您的拦截处理放在HTTP调用
首先,您可以创建一个扩展Http
:
@Injectable()
export class CustomHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
console.log('request...');
return super.request(url, options).catch(res => {
// do something
});
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
console.log('get...');
return super.get(url, options).catch(res => {
// do something
});
}
}
并按如下所述进行注册:
bootstrap(AppComponent, [HTTP_PROVIDERS,
new Provider(Http, {
useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
deps: [XHRBackend, RequestOptions]
})
]);
在调用目标方法之前,可以添加request
和requestError
种类。
对于response
,您需要将一些异步处理插入现有的处理链中。这取决于您的需要,但您可以使用Observable的运算符(如flatMap
)。
最后,对于responseError
,您需要在目标呼叫上调用catch
运算符。这样,当响应中发生错误时,您将收到通知。
此链接可以帮助您:
答案 1 :(得分:18)
<强>更新强>
Angular 4.3.0中引入的新HttpClient
模块支持拦截器https://github.com/angular/angular/compare/4.3.0-rc.0...4.3.0
壮举(常见):新的HttpClient API HttpClient是一个演变的 现有的Angular HTTP API,它与它一起存在于一个单独的 包,@ angular / common / http。这种结构确保了现有的 代码库可以慢慢迁移到新的API。
新的API显着改善了人体工程学和功能 遗留API。部分新功能列表包括:
- 键入的同步响应正文访问,包括对JSON正文类型的支持
- JSON是假定的默认值,不再需要显式解析
- 拦截器允许将中间件逻辑插入管道
- 不可变的请求/响应对象
- 请求上传和响应下载的进度事件
- 请求后验证&amp;基于冲洗的测试框架
<强>原始强>
Angular2还没有(还有)拦截器。您可以扩展Http
,XHRBackend
,BaseRequestOptions
或任何其他相关类(至少在TypeScript和Dart中(不了解普通JS)。
另见
答案 2 :(得分:12)
此存储库中有一个Http @ angular / core-like服务的实现:https://github.com/voliva/angular2-interceptors
您只需在bootstrap上声明该服务的提供程序,添加您需要的任何拦截器,它将可用于所有组件。
import { provideInterceptorService } from 'ng2-interceptors';
@NgModule({
declarations: [
...
],
imports: [
...,
HttpModule
],
providers: [
MyHttpInterceptor,
provideInterceptorService([
MyHttpInterceptor,
/* Add other interceptors here, like "new ServerURLInterceptor()" or
just "ServerURLInterceptor" if it has a provider */
])
],
bootstrap: [AppComponent]
})
答案 3 :(得分:10)
自Angular 4.3开始受到限制(HttpInterCeptors回归4.3)
您可以创建自己的自定义HTTP类并使用rxjs Subject Service重用自定义Http类并在自定义类中实现您的行为。
使用包含一些rxjs主题的“HttpSubjectService”实现自定义Http类。
import { Injectable } from '@angular/core';
import { Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { HttpSubjectService } from './httpSubject.service';
@Injectable()
export class CustomHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private httpSubjectService: HttpSubjectService) {
super(backend, defaultOptions);
//Prevent Ajax Request Caching for Internet Explorer
defaultOptions.headers.append("Cache-control", "no-cache");
defaultOptions.headers.append("Cache-control", "no-store");
defaultOptions.headers.append("Pragma", "no-cache");
defaultOptions.headers.append("Expires", "0");
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
//request Start;
this.httpSubjectService.addSpinner();
return super.request(url, options).map(res => {
//Successful Response;
this.httpSubjectService.addNotification(res.json());
return res;
})
.catch((err) => {
//Error Response.
this.httpSubjectService.removeSpinner();
this.httpSubjectService.removeOverlay();
if (err.status === 400 || err.status === 422) {
this.httpSubjectService.addHttp403(err);
return Observable.throw(err);
} else if (err.status === 500) {
this.httpSubjectService.addHttp500(err);
return Observable.throw(err);
} else {
return Observable.empty();
}
})
.finally(() => {
//After the request;
this.httpSubjectService.removeSpinner();
});
}
}
用于注册CustomHttp类的自定义模块 - 在这里,您可以使用自己的CustomHttp实现覆盖Angular的默认Http实现。
import { NgModule, ValueProvider } from '@angular/core';
import { HttpModule, Http, XHRBackend, RequestOptions } from '@angular/http';
//Custom Http
import { HttpSubjectService } from './httpSubject.service';
import { CustomHttp } from './customHttp';
@NgModule({
imports: [ ],
providers: [
HttpSubjectService,
{
provide: Http, useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, httpSubjectService: HttpSubjectService) => {
return new CustomHttp(backend, defaultOptions, httpSubjectService);
},
deps: [XHRBackend, RequestOptions, HttpSubjectService]
}
]
})
export class CustomHttpCoreModule {
constructor() { }
}
现在我们需要HttpSubjectService实现,我们可以使用“next”语句调用我们的rxjs主题。
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class HttpSubjectService {
//https://github.com/ReactiveX/rxjs/blob/master/doc/subject.md
//In our app.component.ts class we will subscribe to this Subjects
public notificationSubject = new Subject();
public http403Subject = new Subject();
public http500Subject = new Subject();
public overlaySubject = new Subject();
public spinnerSubject = new Subject();
constructor() { }
//some Example methods we call in our CustomHttp Class
public addNotification(resultJson: any): void {
this.notificationSubject.next(resultJson);
}
public addHttp403(result: any): void {
this.http403Subject.next(result);
}
public addHttp500(result: any): void {
this.http500Subject.next(result);
}
public removeOverlay(): void {
this.overlaySubject.next(0);
}
public addSpinner(): void {
this.spinnerSubject.next(1);
}
public removeSpinner(): void {
this.spinnerSubject.next(-1);
}
}
调用我们需要订阅主题的自定义实现。 “app.component.ts”。
import { Component } from '@angular/core';
import { HttpSubjectService } from "../HttpInterception/httpSubject.service";
import { Homeservice } from "../HttpServices/home.service";
@Component({
selector: 'app',
templateUrl: './app.component.html',
})
export class AppComponent {
private locals: AppLocalsModel = new AppLocalsModel();
constructor(private httpSubjectService : HttpSubjectService, private homeService : Homeservice) {}
ngOnInit(): void {
this.notifications();
this.httpRedirects();
this.spinner();
this.overlay();
}
public loadServiceData(): void {
this.homeService.getCurrentUsername()
.subscribe(result => {
this.locals.username = result;
});
}
private overlay(): void {
this.httpSubjectService.overlaySubject.subscribe({
next: () => {
console.log("Call Overlay Service");
}
});
}
private spinner(): void {
this.httpSubjectService.spinnerSubject.subscribe({
next: (value: number) => {
console.log("Call Spinner Service");
}
});
}
private notifications(): void {
this.httpSubjectService.notificationSubject.subscribe({
next: (json: any) => {
console.log("Call Notification Service");
}
});
}
private httpRedirects(): void {
this.httpSubjectService.http500Subject.subscribe({
next: (error: any) => {
console.log("Navigate to Error Page");
}
});
this.httpSubjectService.http403Subject.subscribe({
next: (error: any) => {
console.log("Navigate to Not Authorized Page");
}
});
}
}
class AppLocalsModel {
public username : string = "noch nicht abgefragt";
}
SINCE ANGULAR 4.3你可以使用InterCeptors
在Angular 4.3中你有本机拦截器,你可以实现自己的东西,比如重定向服务器错误500
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class SxpHttp500Interceptor implements HttpInterceptor {
constructor(public router: Router) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(evt => { }).catch(err => {
if (err["status"]) {
if (err.status === 500) {
this.router.navigate(['/serverError', { fehler: JSON.stringify(err) }]);
}
}
return Observable.throw(err);
});
}
}
您需要在providers Array
中的核心模块中注册它import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Router } from '@angular/router';
import { SxpHttp500Interceptor } from "./sxpHttp500.interceptor";
....
providers: [
{
provide: HTTP_INTERCEPTORS, useFactory: (router: Router) => { return new SxpHttp500Interceptor(router) },
multi: true,
deps: [Router]
}
]
答案 4 :(得分:8)
使用Angular 4.3.1版本,现在有一个名为 HttpInterceptor 的接口。
这是指向文档的链接: https://angular.io/api/common/http/HttpInterceptor
基本上写成任何其他服务:
@Injectable()
export class ExceptionsInterceptor implements HttpInterceptor {
constructor(
private logger: Logger,
private exceptionsService: ExceptionsService,
private notificationsService: NotificationsService
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.do((event) => {
// Do nothing here, manage only errors
}, (err: HttpErrorResponse) => {
if (!this.exceptionsService.excludeCodes.includes(err.status)) {
if (!(err.status === 400 && err.error['_validations'])) {
this.logger.error(err);
if (!this.notificationsService.hasNotificationData(err.status)) {
this.notificationsService.addNotification({ text: err.message, type: MessageColorType.error, data: err.status, uid: UniqueIdUtility.generateId() });
}
}
}
});
}
}
然后,由于您将此视为普通服务,因此您必须在应用模块的提供商中添加此行:
{ provide: HTTP_INTERCEPTORS, useClass: ExceptionsInterceptor, multi: true }
希望它可以提供帮助。
答案 5 :(得分:2)
Angular 4.3 现在支持Http拦截器开箱即用。 看看如何使用它们: https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors
答案 6 :(得分:0)
我已经使用以下节点模块发布了拦截器。我们为内部目的创建了这个模块,最后我们在npm包管理器中发布了 npm install angular2-resource-and-ajax-interceptor 的 https://www.npmjs.com/package/angular2-resource-and-ajax-interceptor 强>
答案 7 :(得分:0)
正如@squadwuschel指出的那样,正在开展工作以将此功能引入@ angular / http。这将是一个新的HttpClient API的形式。
有关详细信息和当前状态,请参阅https://github.com/angular/angular/pull/17143。
答案 8 :(得分:0)
尝试Covalent from Teradata,它们为Angular和Angular Material提供了许多扩展。
检查HTTP部分,它在Angular和RESTService中提供缺少的http拦截器(类似于restangular)。
我已在我的示例中通过 Covalent HTTP实施了JWT令牌身份验证,请点击此处。
https://github.com/hantsy/angular2-material-sample/blob/master/src/app/core/auth-http-interceptor.ts
请阅读我的开发说明,Handle token based Authentication via IHttpInterceptor。
答案 9 :(得分:0)
Angular2 donot支持像angular1
这样的httpinterceptor这是在angular2中使用httpinterceptor的一个很棒的例子。