Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多个HTTP拦截器中的next.handle(request)失败:未定义

多个HTTP拦截器中的next.handle(request)失败:未定义
EN

Stack Overflow用户
提问于 2020-06-29 10:12:42
回答 1查看 4.3K关注 0票数 2

在一个项目中,我使用两个HTTP拦截器:一个向每个请求添加一个JWT令牌,另一个拦截传入的401错误状态。

我调用一个单独的程序来获取此服务中我的应用程序的所有反馈:

代码语言:javascript
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { environment } from '@environments/environment';
import { Feedback } from '@app/_models/feedback';

@Injectable({ providedIn: 'root' })
export class FeedbackService {
    constructor(
        private http: HttpClient
    ) {}

    getAll() {
        return this.http.get<Feedback[]>(`${environment.apiUrl}/feedback`);
    }

    getById(id: string) {
        return this.http.get<Feedback>(`${environment.apiUrl}/feedback/${id}`);
    }

    delete(id: string) {
        return this.http.delete(`${environment.apiUrl}/feedback/${id}`);
    }
}

JWT拦截器:

代码语言:javascript
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } 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>> {
        // add auth header with jwt if user is logged in and request is to the api url
        const authenticatedUser = this.auth.getAuthenticatedUser();
        if (authenticatedUser == null) {
            return;
        }
        authenticatedUser.getSession( (err, session) => {
            if (err) {
                console.log(err);
                return;
            }
            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) {
                request = request.clone({
                    setHeaders: {
                        Authorization: token,
                    }
                });
            }

            return next.handle(request);
        });
    }
}

错误拦截器:

代码语言:javascript
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

import { AccountService } from '@app/_services';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private accountService: AccountService) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(next.handle(request));
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                this.accountService.logout();
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }));
    }
}

当我在app.module中提供两个拦截器时,

代码语言:javascript
运行
AI代码解释
复制
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },

我总是收到下面的错误提示。这是因为next.handle(request)显然是undefined,而我真的不知道为什么。只使用错误拦截器是没有问题的。

代码语言:javascript
运行
AI代码解释
复制
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会产生以下错误,我不知道它是从哪里来的。当然,我会希望两者都使用。在配置多个拦截器时,我是否遗漏了什么?

代码语言:javascript
运行
AI代码解释
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-29 13:12:24

重写你的JwtInterceptor:

代码语言:javascript
运行
AI代码解释
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62635885

复制
相关文章
ng6中,在HTTP拦截器里,异步请求数据,之后再返回拦截器继续执行用户请求的方法研究
      我现在项目就是利用拦截器,在请求头里增加:'Authorization': this.storage.token 的请求头。
申君健
2018/09/21
2K0
ng6中,在HTTP拦截器里,异步请求数据,之后再返回拦截器继续执行用户请求的方法研究
http & request & response的学习
HTTP: 1. 概念: * Hyper Text Transfer Protocol 超文本传输协议 * 传输协议:定义了,客户端和服务器端通信时,发送数据的格式 * 特点: 1.基于TCP/IP的高级协议 2.默认端口号:80 3.基于请求/响应模型的:一次请求对应一次响应 4.无状态的:每次请求之间相互独立,不能交互数据 * 历史版本: * 1.0:每一次请求响应都会建立新的连接 * 1.1:复用连接 2.
Rochester
2020/09/01
7250
HTTP请求方法(HTTP Request Method)
HTTP请求方法(HTTP Request Method)共有15种,根据HTTP标准,HTTP请求可以使用多种请求方法。 HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
很酷的站长
2022/12/02
1.1K0
FastAPI(9)- 多个 Request Body
除了路径参数 item_id 是必传的,查询参数 name 和请求体 item 都是可选非必传
小菠萝测试笔记
2021/09/27
9440
Spring 拦截器流程及多个拦截器的顺序
拦截器是 Spring MVC 中的组件,它可以在进入请求方法前做一些操作,也可以在请求方法后和渲染视图后做一些事情。
码农UP2U
2021/05/14
1.7K0
Spring 拦截器流程及多个拦截器的顺序
WordPress 技巧:解决 HTTP Request 中 SSL certificate Problem
在开发中,使用 HTTP Request 去远程服务器 get 数据和 post 数据到远程服务器,是非常常见的操作,但是如果远程服务器是 HTTPS 加密的话,你进行 HTTP Request 操作的时候就会发声如下的问题:
Denis
2023/04/15
4770
Asp.Net Core API 需要认证时发生重定向的解决方法
使用 .Net Core 开发 API 时, 有些 API 是需要认证, 添加了 [Authorize] 标记, 代码如下所示:
beginor
2020/08/07
1.9K0
Angular HttpClient 拦截器
在之前的 Angular 6 HttpClient 快速入门 文章中,我们已经简单介绍了 Http 拦截器。本文将会进一步分析一下 Http 拦截器。拦截器提供了一种用于拦截、修改请求和响应的机制。这个概念与 Node.js 的 Express 框架中间件的概念类似。拦截器提供的这种特性,对于日志、缓存、请求授权来说非常有用。
阿宝哥
2019/11/05
2.7K0
idea启动多个tomcat失败
Intellij idea中,为在本地调试两个系统之间的调用,配置两个本地tomcat server,设置不同的端口号,如8081和8082,Deploy中加入两个系统各自的Artifact xxx:war, Application context设置为“/“,即访问地址分别为http://localhost:8081/ 和 http://localhost:8082/ 。 问题来了,分别单独启动两个server时都能成功;但是同时启动两个系统时,两个系统都会出现问题。其中较先启动的server报错为:St
欢醉
2018/01/22
2.7K0
Web编程-Servlet&HTTP&Request
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/12/11
3420
Error parsing HTTP request header Note: further occurrences of HTTP
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
无可奉告丶
2021/01/31
4.5K0
解决The HTTP request is not acceptable for the requested resource
Vue项目中报错The HTTP request is not acceptable for the requested resource
用户10275458
2022/12/21
1.1K0
点击加载更多

相似问题

角4 Http拦截器:next.handle(.).do不是函数

49

使用没有next.handle的角度拦截器

16

Vuejs http拦截器失败

01

角拦截器:如何管理重试(嵌套next.handle())?

13

角HTTP拦截器订阅可观测到的,然后返回next.handle但抛出TypeError:您提供了“未定义”

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档