Javascript 多个HTTP拦截器中的句柄(请求)失败:未定义
在一个项目中,我使用2个HTTP拦截器:1个向每个请求添加JWT令牌,另一个截获传入的401错误状态 我调用一个单独的程序来获取此服务中我的应用程序的所有反馈:Javascript 多个HTTP拦截器中的句柄(请求)失败:未定义,javascript,angular,rxjs,angular-http-interceptors,Javascript,Angular,Rxjs,Angular Http Interceptors,在一个项目中,我使用2个HTTP拦截器:1个向每个请求添加JWT令牌,另一个截获传入的401错误状态 我调用一个单独的程序来获取此服务中我的应用程序的所有反馈: 从'@angular/core'导入{Injectable}; 从'@angular/common/http'导入{HttpClient}; 从'@environments/environment'导入{environment}; 从'@app/_models/Feedback'导入{Feedback}; @可注射({providedI
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpClient};
从'@environments/environment'导入{environment};
从'@app/_models/Feedback'导入{Feedback};
@可注射({providedIn:'root'})
导出类反馈服务{
建造师(
私有http:HttpClient
) {}
getAll(){
返回这个.http.get(`${environment.apirl}/feedback`);
}
getById(id:string){
返回这个.http.get(`${environment.apirl}/feedback/${id}`);
}
删除(id:string){
返回此.http.delete(`${environment.apirl}/feedback/${id}`);
}
}
JWT拦截器:
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import { environment } from '@environments/environment';
import { AuthorizationService } from 'src/shared/authorization.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private auth: AuthorizationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.getSessionWithAuthReq(request, next));
}
async getSessionWithAuthReq(request: HttpRequest<any>, next: HttpHandler){
const authenticatedUser = this.auth.getAuthenticatedUser();
if (authenticatedUser) {
const authRequest: HttpRequest<any> = await new Promise( (resolve) => {
authenticatedUser.getSession( (err, session) => {
if (err) {
console.log(err);
// want to go on without authenticating if there is an error from getting session
return resolve(request);
}
const isApiUrl = request.url.startsWith(environment.apiUrl);
const token = session.getIdToken().getJwtToken();
const headers = new Headers();
headers.append('Authorization', token);
if (this.auth.isLoggedIn() && isApiUrl) {
const req = request.clone({
setHeaders: {
Authorization: token,
}
});
return resolve(req);
}
return resolve(request);
});
});
return next.handle(authRequest).toPromise();
}
return next.handle(request).toPromise();
}
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpRequest,HttpHandler,HttpEvent,HttpInterceptor};
从“rxjs”导入{Observable};
从'@environments/environment'导入{environment};
从'src/shared/authorization.service'导入{AuthorizationService};
@可注射()
导出类JwtInterceptor实现HttpInterceptor{
构造函数(私有身份验证:授权服务){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
//如果用户已登录,并且请求已发送到api url,则使用jwt添加auth头
const authenticatedUser=this.auth.getAuthenticatedUser();
if(authenticatedUser==null){
返回;
}
authenticatedUser.getSession((错误,会话)=>{
如果(错误){
控制台日志(err);
返回;
}
const isApiUrl=request.url.startsWith(environment.apiUrl);
const token=session.getIdToken().getJwtToken();
常量头=新头();
headers.append('Authorization',token);
if(this.auth.isLoggedIn()&&isApiUrl){
request=request.clone({
集合标题:{
授权:令牌,
}
});
}
下一步返回。处理(请求);
});
}
}
错误拦截器:
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import { environment } from '@environments/environment';
import { AuthorizationService } from 'src/shared/authorization.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private auth: AuthorizationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.getSessionWithAuthReq(request, next));
}
async getSessionWithAuthReq(request: HttpRequest<any>, next: HttpHandler){
const authenticatedUser = this.auth.getAuthenticatedUser();
if (authenticatedUser) {
const authRequest: HttpRequest<any> = await new Promise( (resolve) => {
authenticatedUser.getSession( (err, session) => {
if (err) {
console.log(err);
// want to go on without authenticating if there is an error from getting session
return resolve(request);
}
const isApiUrl = request.url.startsWith(environment.apiUrl);
const token = session.getIdToken().getJwtToken();
const headers = new Headers();
headers.append('Authorization', token);
if (this.auth.isLoggedIn() && isApiUrl) {
const req = request.clone({
setHeaders: {
Authorization: token,
}
});
return resolve(req);
}
return resolve(request);
});
});
return next.handle(authRequest).toPromise();
}
return next.handle(request).toPromise();
}
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpRequest,HttpHandler,HttpEvent,HttpInterceptor};
从“rxjs”导入{observatable,throwerr};
从“rxjs/operators”导入{catchError};
从'@app/_services'导入{AccountService};
@可注射()
导出类ErrorInterceptor实现HttpInterceptor{
构造函数(私有accountService:accountService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
console.log(next.handle(request));
返回next.handle(request).pipe(catchError(err=>{
如果(错误状态===401){
//如果api返回401响应,则自动注销
此参数为.accountService.logout();
}
const error=err.error.message | | err.statusText;
返回投掷器(错误);
}));
}
}
当我在app.module中提供两个拦截器时
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
我总是在说下面的话时出错。发生这种情况是因为next.handle(request)
显然是未定义的,我真的不知道为什么。仅使用错误拦截器不会产生任何问题
ERROR TypeError: Cannot read property 'pipe' of undefined
at ErrorInterceptor.intercept (error.interceptor.ts:14)
at HttpInterceptorHandler.handle (http.js:1958)
at HttpXsrfInterceptor.intercept (http.js:2819)
at HttpInterceptorHandler.handle (http.js:1958)
at HttpInterceptingHandler.handle (http.js:2895)
at MergeMapSubscriber.project (http.js:1682)
at MergeMapSubscriber._tryNext (mergeMap.js:46)
at MergeMapSubscriber._next (mergeMap.js:36)
at MergeMapSubscriber.next (Subscriber.js:49)
at Observable._subscribe (subscribeToArray.js:3)
仅使用JwtInterceptor会产生以下错误,我无法找出它的来源。当然,我想两者都用。配置多个拦截器时我是否遗漏了什么
ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeTo (subscribeTo.js:27)
at subscribeToResult (subscribeToResult.js:11)
at MergeMapSubscriber._innerSub (mergeMap.js:59)
at MergeMapSubscriber._tryNext (mergeMap.js:53)
at MergeMapSubscriber._next (mergeMap.js:36)
at MergeMapSubscriber.next (Subscriber.js:49)
at Observable._subscribe (subscribeToArray.js:3)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at MergeMapOperator.call (mergeMap.js:21)
重写JWT拦截器:
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import { environment } from '@environments/environment';
import { AuthorizationService } from 'src/shared/authorization.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private auth: AuthorizationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(this.getSessionWithAuthReq(request, next));
}
async getSessionWithAuthReq(request: HttpRequest<any>, next: HttpHandler){
const authenticatedUser = this.auth.getAuthenticatedUser();
if (authenticatedUser) {
const authRequest: HttpRequest<any> = await new Promise( (resolve) => {
authenticatedUser.getSession( (err, session) => {
if (err) {
console.log(err);
// want to go on without authenticating if there is an error from getting session
return resolve(request);
}
const isApiUrl = request.url.startsWith(environment.apiUrl);
const token = session.getIdToken().getJwtToken();
const headers = new Headers();
headers.append('Authorization', token);
if (this.auth.isLoggedIn() && isApiUrl) {
const req = request.clone({
setHeaders: {
Authorization: token,
}
});
return resolve(req);
}
return resolve(request);
});
});
return next.handle(authRequest).toPromise();
}
return next.handle(request).toPromise();
}
}
从'@angular/common/http'导入{HttpInterceptor,HttpHandler,HttpRequest,HttpEvent};
从“@angular/core”导入{Injectable};
从'rxjs'导入{observatable,from};
从'@environments/environment'导入{environment};
从'src/shared/authorization.service'导入{AuthorizationService};
@可注射()
导出类JwtInterceptor实现HttpInterceptor{
构造函数(私有身份验证:授权服务){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
从(this.getSessionWithAuthReq(请求,下一步))返回;
}
异步getSessionWithAuthReq(请求:HttpRequest,下一步:HttpHandler){
const authenticatedUser=this.auth.getAuthenticatedUser();
if(authenticatedUser){
const authRequest:HttpRequest=等待新承诺((解析)=>{
authenticatedUser.getSession((错误,会话)=>{
如果(错误){
控制台日志(err);
//如果获取会话时出错,是否希望在不进行身份验证的情况下继续
返回解析(请求);
}
const isApiUrl=request.url.startsWith(environment.apiUrl);
const token=session.getIdToken().getJwtToken();
常量头=新头();
headers.append('Authorization',token);
if(this.auth.isLoggedIn()&&isApiUrl){
const req=request.clone({
集合标题:{
授权:令牌,
}
});
返回解析(req);
}
返回解析(请求);
});
});
返回next.handle(authRequest.toPromise();
}
返回next.handle(request.toPromise();
}
}
JwtInterceptor.intercept()
并不总是返回可观察的。哇,谢谢!所以据我所知,我的代码的主要问题是我并不总是返回任何消息