在角度5+中使用自定义HttpInterceptors时,我收到以下奇怪的依赖注入行为.
以下简化代码工作正常:
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.auth.getToken();
return next.handle(req);
}
}
export class AuthService {
token: string;
constructor() {
console.log('AuthService.constructor');
}
}
Run Code Online (Sandbox Code Playgroud)
然而....
当AuthService具有1个或更多依赖性时,例如
export class AuthService {
token: string;
constructor(private api: APIService) {
console.log('AuthService.constructor');
}
}
Run Code Online (Sandbox Code Playgroud)
angular尝试重复创建新实例,AuthService直到收到以下错误:
日志显示AuthService.constructor消息~400次
和
Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule
和
app.component.html:44错误RangeError:超出最大调用堆栈大小
然后我尝试使用Injector类注入服务 -
export class AuthService {
token: …Run Code Online (Sandbox Code Playgroud) 有时,200 ok即使出现错误,我正在使用的API也会返回.响应JSON对象将类似于:
{
error: true
}
Run Code Online (Sandbox Code Playgroud)
我已经构建了一个$ http response拦截器,只是检查这个错误并拒绝它.我希望它然后跳进我的responseError功能:
$httpProvider.interceptors.push(function($q) {
return {
response: function (response) {
if (response.data.error) {
// There has been an error, reject this response
return $q.reject(response);
}
return response;
},
responseError: function(rejection) {
// Display an error message to the user
...
return $q.reject(rejection);
}
}
});
Run Code Online (Sandbox Code Playgroud)
问题是,即使在拒绝响应之后,我的responseError函数也没有被调用.它被调用500错误等,所以我知道它正在工作.我希望拒绝做同样的事情.
来自文档:
responseError: interceptor gets called when a previous interceptor threw an error or resolved with a …Run Code Online (Sandbox Code Playgroud) 我的webapp正在谈论的API有时会超载,如果它无法处理请求,则发送500内部服务器错误.
我的Web应用程序可以发送100多个不同的请求,因此如果我单独执行重试,则会花费数小时的打字时间.
我已经在使用$ httpProvider拦截器,这里是(简化)
$httpProvider.interceptors.push(function ($q) {
return {
responseError: function (response) {
switch (response.status) {
case 401 :
window.location = "/";
alert('Session has expired. Redirecting to login page');
break;
case 500 :
// TODO: retry the request
break;
}
return $q.reject(response);
}
};
});
Run Code Online (Sandbox Code Playgroud)
从服务器获取500响应代码后,如何重新发送请求?
我按照这篇文章在项目上实现了类似的ajax loader映像:
我的实现有一些不同之处:
$rootScope到emit,而不是broadcast和我也用$rootScope的指令来处理该事件.$rootScope.$on在事件处理程序内第一个被触发的事件(显示或隐藏)之后解除指令侦听器的绑定.我认为这些是与链接帖子的主要区别,不确定它们是否与我的问题相关,但以防它们是......
处理加载程序隐藏事件时,加载程序已经消失,除非刷新页面,否则我不会再显示它,但我仍然有后台http请求刷新当前页面上的数据.这些请求仍然会被截获并触发新的显示/隐藏事件,这些事件不再需要/处理.我只需要第一次秀和第一次隐藏,就是这样.
什么是删除我$httpProvider在第一个隐藏事件被触发后添加到的HTTP拦截器的正确方法?
我知道我们使用a添加了拦截器,$httpProvider.interceptors.push()但是当我不再需要拦截器时,我不知道如何将其弹出.
我有一个auth-interceptor.service.ts处理请求
import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {Cookie} from './cookie.service';
import {Router} from '@angular/router';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Clone the request to add the new header.
const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey, Cookie.getToken())});
// Pass on the cloned request instead of the original request.
return next.handle(authReq).catch(this.handleError);
}
private handleError(err: HttpErrorResponse): Observable<any> {
console.log(err);
if …Run Code Online (Sandbox Code Playgroud) typescript angular-http angular-http-interceptors angular angular-httpclient
如果当前访问令牌已过期,我正在尝试刷新访问令牌。
我一次发送多个请求,我想创建一种队列,因此其他请求不会请求刷新令牌路由。
我在谷歌上搜索了一些最佳实践和示例,并找到了以下针对 Angular 6 和 rxjs v6 的解决方案,它使用了 BehaviourSubject 和 switchMaps。(请看附件代码)
但是我使用的是 Angular 8 (8.1) 和 rxjs v6.4,这个解决方案对我不起作用。
它根本没有达到switchMap在this.authService.requestAccessToken().pipe。(使用console.log测试)
但是,如果我发表评论return this.refreshTokenSubject.pipe并返回,next.handle(request)它会到达那个 switchMap,但我的其他请求都失败了。
您知道是否有任何更改,或者我应该尝试以其他方式执行此操作吗?
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { AuthService } from './auth.service';
import { Observable, BehaviorSubject, Subject } from 'rxjs';
import { switchMap, take, filter } from 'rxjs/operators';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private refreshTokenInProgress = …Run Code Online (Sandbox Code Playgroud) rxjs angular-http-interceptors refresh-token angular angular8
我试图通过将拦截器添加到providers组件本身的数组( { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true })来将拦截器添加到独立组件,但它不起作用......
这是代码的链接
谢谢 :)
我有以下拦截器:
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private tokenService: TokenService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.tokenService.getToken();
if (token) {
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next.handle(authReq);
}
return next
.handle(req)
//
.getSomehowTheResponse()
.andSaveTheTokenInStorage()
.andPropagateNextTheResponse()
}
}
Run Code Online (Sandbox Code Playgroud)
我想从本地存储中的响应头保存令牌,所有教程都显示如何拦截请求,但不是很清楚响应.
我有一个HttpInterceptor来捕获错误并在模态中显示它们.除了错误代码和消息之外,我还想显示响应的主体,它实际上包含更准确的错误描述(例如,在500内部服务器错误上).我怎样才能在角度上实现这一目标?(我使用的是4.3.6版本.)
我已经查看了相关的问题,但像HttpErrorResponse._body或类似的答案对我不起作用.此外,在控制台中检查错误响应时,HttpErrorResponse.error设置为null.
以下是我的拦截器目前的样子:
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
public constructor(private httpErrorService: HttpErrorService) { }
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {
}, (error: HttpErrorResponse) => {
console.log('HTTPERROR INTERCEPTOR');
console.log(error);
if (error.status >= 400) {
this.httpErrorService.onError(error);
}
});
}
}
Run Code Online (Sandbox Code Playgroud) 最近我一直在使用Angular HttpClient拦截器.
我添加了与某些HTTP GET方法相对应的标头,对于某些我不需要这些标头.
如何告诉我的拦截器有条件地将拦截器添加到那些方法?我甚至可以拆分服务,例如一个服务用于标头,一个服务没有标题,一个用于不同的标题,一个用于不同的标题.
NgModule提供商
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},{
provide: HTTP_INTERCEPTORS,
useClass: AngularInterceptor,
multi: true,
}
Run Code Online (Sandbox Code Playgroud)
MyInterceptors
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authReq = req.clone({headers: req.headers.set('X-Auth-Token', "-------------------------")});
return next.handle(authReq);
}
}
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {}, err => {
if(err instanceof HttpErrorResponse){
console.log("Error Caught By Interceptor");
//Observable.throw(err);
}
});
}
}
Run Code Online (Sandbox Code Playgroud) angular-http angular-http-interceptors angular angular-httpclient