我使用$http拦截器来捕获 ajax 提交后的所有事件。由于某种原因,我无法抛出requestError. 我已经设置了一个测试应用程序来尝试调用requestError,但到目前为止我只能获取多个responseErrors.
来自angularjs文档:
requestError:当前一个拦截器抛出错误或通过拒绝解决时,拦截器被调用。
这是我的测试代码。
.factory('httpInterceptor',['$q',function(q){
var interceptor = {};
var uniqueId = function uniqueId() {
return new Date().getTime().toString(16) + '.' + (Math.round(Math.random() * 100000)).toString(16);
};
interceptor.request = function(config){
config.id = uniqueId();
console.log('request ',config.id,config);
return config;
};
interceptor.response = function(response){
console.log('response',response);
return response;
};
interceptor.requestError = function(config){
console.log('requestError ',config.id,config);
return q.reject(config);
};
interceptor.responseError = function(response){
console.log('responseError ',response.config.id,response);
return q.reject(response);
};
return interceptor;
}])
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}]) …Run Code Online (Sandbox Code Playgroud) 我尝试为使用 HttpClient 执行的每个 HTTP 请求设置 10 秒的默认超时。我有一个拦截器可以向标头添加一些值,并且我已经读到要设置超时,您必须使用“超时”RxJS 运算符,如下所示:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { timeout } from 'rxjs/operators/timeout';
@Injectable()
export class APIInterceptor implements HttpInterceptor {
constructor() {
}
intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// NOTE: The following 'authToken' and 'user_id' values are obtained through a global service
const authReq = req.clone({
headers: new HttpHeaders ({
'Content-Type': 'application/json',
'X_TOKEN_AUTH': authToken,
'X_IDUSER': …Run Code Online (Sandbox Code Playgroud) 我一直在寻找测试 Angular Interceptor 代码的错误处理方法,但我似乎不知道如何进行。
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService, private router: Router) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(err => {
let errorMessage = '';
if (err instanceof HttpErrorResponse) { // server side error
switch (err.status) {
case 401:
// auto logout if 401 response returned from api
errorMessage = "Ongeldige inloggegevens"
break;
case 500: //server error
errorMessage = `Error Status: ${err.status}\nMessage: ${err.message}`;
this.router.navigate([`/code500`]);
break;
}
return throwError(errorMessage);
}
})
) …Run Code Online (Sandbox Code Playgroud) 我想知道Angular.js $ http拦截器是否在整个应用程序中共享.
我们假设我有一个myDependentApp模块,在很多应用程序之间共享.该模块有一些拦截器配置为控制$ http请求/响应.我通过在应用程序引导程序中声明它来包含该模块:
angular.module('myApp', ['myDependentApp']);
Run Code Online (Sandbox Code Playgroud)
我有应用程序模板:
<html ng-app="myApp">
Run Code Online (Sandbox Code Playgroud)
是myDependentApp的拦截器会活跃myApp吗?
感谢帮助.
我需要将必要的HMAC标头附加到请求中.这应该不是很困难,但我开始感到沮丧.以下代码有什么问题.我正在进行的实际http调用; 我自己运行了这个调用,它返回了必要的数据.它在拦截器内部不起作用.
我只是希望在为此拦截器添加白名单或黑名单以及其他可自定义数据之前使当前实现正常工作.这不是关于hmac的问题,而是有了承诺.
此拦截器中的错误是整个承诺行从$ http(...)开始.当我删除此块并按原样使用它(减去承诺执行)它工作正常.一旦我取消注释该线就会卡在一个循环中并崩溃铬.我读过的每个地方都说它是如何完成的,但这显然不起作用.
function requestInterceptor(config){
var $http = $injector.get('$http');
var deferred = $q.defer();
$http.get(hmacApiEndpoint, {cache: true}).then(function(data){
console.log('HMAC - Success', data)
deferred.resolve(config)
}, function(config){
console.log('HMAC - Error', config)
deferred.resolve(config)
})
return deferred.promise;
}
return {
request: requestInterceptor
};
Run Code Online (Sandbox Code Playgroud)
这是否与angulars $ http promise与'$ q'不同的实现有关?
javascript angularjs angular-http-interceptors angular-promise
在服务器自动更新令牌的上下文中,我正在努力解决基本问题:从响应中获取头数据.
它似乎与CORS无关,因为我的Node/express allwos授权/ x-access-token并相应地响应(请参阅下面的网络选项卡screeencap).
我希望看到工作的第一步是简单地从响应中读取标题.请参阅我的代码,它是文档中的样板文件.获取"Content-Length"的事件返回null.
AUTH-service.ts
login(username:string, password:string):Observable<boolean>{
this.loggedIn = false;
return new Observable( (observer:Observer<boolean>) => {
const body = {user: username, pwd: password};
const url = this.config.API_ENDPOINT_PUBLIC_AUTH;
this.httpClient.post(url, body, {
responseType: 'text',
observe: "response"
}).first().subscribe(
(response:HttpResponse<string>) => {
// DEBUG
console.log(response.headers.get('Authorization'));
console.log(response.headers.get('X-Test-Header'));
console.log(response.headers.get('Content-length'));
this.token = response.headers.get('Authorization');
this.storeToken(this.token);
this.currentUser = username;
this.loggedIn = true;
this.authChanged$.next('auth');
observer.next(true);
},
(err) => observer.next(false),
() => {},
);
});
}
Run Code Online (Sandbox Code Playgroud)
控制台输出:
空值
空值
空值
将此与此请求的网络选项卡的内容进行比较:
不用说我的HttpInterceptor也不起作用 - 在响应中提供"Authorization"标头时,它将该值用作新标记.这样可以实现令牌的自动续订:
token.interceptor.ts
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> …Run Code Online (Sandbox Code Playgroud) 我创建了这个http拦截器:
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
public my_status: boolean = true;
private _statusChange: Subject<boolean> = new Subject<boolean>();
public statusChange$ = this._statusChange.asObservable();
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.changeStatus(false);
const my_req = req.clone({
url: API_PATH + req.url
});
return next
.handle(my_req)
.do(event => {
if (event instanceof HttpResponse)
this.changeStatus(true);
});
}
private changeStatus(status: boolean) {
this.my_status = status;
this._statusChange.next(this.my_status);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的组件中,我做到了:
export class AppComponent implements OnInit {
public my_status: boolean;
constructor(private httpInterceptor: NoopInterceptor) {
this.my_status = httpInterceptor.my_status;
httpInterceptor.statusChange$.subscribe(this.changeStatus); …Run Code Online (Sandbox Code Playgroud) 我的流程是登录页面 - >主页.
登录页面没有令牌,登录后,服务器提供令牌,用户被重定向到主页.
主页将令牌发送到服务器,令牌验证,服务器发回数据显示在前端.
HttpInterceptor在登录请求时触发Cannot read property 'token' of null.我想让拦截器以某种方式忽略登录api请求,并且只在令牌存在时才拦截后续调用.
我有一个使用注册了HttpInterceptor的插件的应用程序。
现在,我需要创建自己的拦截器,该拦截器必须在其他拦截器之前运行,因为它将更改其他拦截器使用的localStorage中的某些值。
注册新的HttpInterceptor时如何影响执行顺序?
Angular 7错误拦截器–原始调用存在问题我编写了一个拦截器来捕获所有401错误。如果发生此类错误,则应尝试获取新的JWT令牌,如果可行,请重复原始请求。到目前为止,拦截器已经起作用。我的问题是,在我给它新令牌后发出的原始请求不会在附加到原始可观察对象的订阅中再次终止。
原始要求
零件:
this.serviceModel.getSearchItems(si).subscribe(res => {
this.resultData = res;
});
Run Code Online (Sandbox Code Playgroud)
服务模型
public getSearchItems(si: SearchInfo): Observable<VoList<SearchResultItemVO>> {
return this.post<VoList<SearchResultItemVO>>(`/api/Search/GetSearchItems`, si, null, SearchResultItemVO);
}
Run Code Online (Sandbox Code Playgroud)
拦截器
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private serviceModel: SharedAccountServiceModel) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).catch(err => {
return this.handleError(err, request, next);
});
}
handleError(err, request: HttpRequest<any>, next: HttpHandler) {
if (err.status === 401) {
if (!!localStorage.getItem('auth_token') && !!localStorage.getItem('refresh_token')) {
this.serviceModel.refreshlogin().switchMap(res => {
return next.handle(this.addAuthenticationToken(request));
})
.subscribe();
}
else {
localStorage.removeItem('accessinfo');
localStorage.removeItem('auth_token');
localStorage.removeItem('userid'); …Run Code Online (Sandbox Code Playgroud) angular ×7
angularjs ×3
javascript ×3
angular5 ×1
http-headers ×1
jwt ×1
rxjs ×1
unit-testing ×1