angular之interceptors拦截器

本文介绍了AngularJS中HTTP拦截器的使用方法及其在请求和响应过程中的作用。通过一个具体的示例,展示了如何创建一个自定义的拦截器服务工厂,并将其注册到$httpProvider.interceptors数组中。
<!DOCTYPE html>
<html ng-app="nickApp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title>interceptors</title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
    <script>
        /*
         $http service在Angular中用于简化与后台的交互过程,其本质上使用XMLHttpRequest或JSONP进行与后台的数据交互。
         在与后台的交互过程中,可能会对每条请求发送到Server之前进行预处理(如加入token),或者是在Server返回数据到达客户端还未被处理之前进行预处理(如将非JSON格式数据进行转换);
         当然还有可能对在请求和响应过程过发生的问题进行捕获处理。所以Angular为我们提供了$http拦截器,用来实现上述需求。*/
        /*
         $httpProvider中有一个 interceptors 数组,而所谓拦截器只是一个简单的注册到该数组中的常规服务工厂。
         1 首先 创建一个拦截器服务工厂
         */
        angular.module('nickApp', [])
                .factory('NickInterceptor', ['$q', function ($q) {
                    return {
                        // 可选,拦截成功的请求
                        /*
                         该方法会在$http发送请求到后台之前执行,因此你可以修改配置或做其他的操作。
                         该方法接收请求配置对象(request configuration object)作为参数,然后必须返回配置对象或者promise 。
                         如果返回无效的配置对象或者 promise 则会被拒绝,导致$http 调用失败
                         */
                        request: function (config) {
                            // 进行预处理
                            // 例如加令牌
                            config.headers['Authorization'] = 'token666';
                            /*
                             Request Headers
                             token:token666 //加的令牌
                             */
                            return config || $q.when(config);
                        },

                        // 可选,拦截成功的响应
                        /*
                         该方法会在$http接收到从后台过来的响应之后执行,因此你可以修改响应或做其他操作。
                         该方法接收响应对象(response object)作为参数,
                         然后必须返回响应对象或者promise。响应对象包括了请求配置(request configuration),头(headers),状态(status)和从后台过来的数据(data)。
                         如果返回无效的响应对象或者 promise 会被拒绝,导致$http调用失败。
                         */
                        response: function (response) {
                            // 进行预处理
                            // 例如 JSON.parse(response)等
                            return response || $q.when(reponse);
                        },

                        // 可选,拦截失败的请求
                        /*
                         有时一个请求发送失败或者被拦截器拒绝了。requestError拦截器会捕获那些被上一个请求拦截器中断的请求。
                         它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如关闭遮罩层,显示进度条,激活按钮和输入框之类的。
                         */
                        requestError: function (rejection) {
                            // 对失败的请求进行处理
                            // 例如 统一的弹窗提示

                            return $q.reject(rejection);
                        },

                        // 可选,拦截失败的响应
                        /*
                         有时候我们后台调用失败了。也有可能它被一个请求拦截器拒绝了,或者被上一个响应拦截器中断了。
                         在这种情况下,响应异常拦截器可以帮助我们恢复后台调用。
                         */
                        responseError: function (rejection) {
                            // 对失败的响应进行处理
                            // 例如 统一的弹窗提示

                            return $q.reject(rejection);
                        }
                    };
                }])
                /*
                 $httpProvider中有一个 interceptors 数组,而所谓拦截器只是一个简单的注册到该数组中的常规服务工厂。
                 2 在config方法中,将拦截器加入到$httpProvider.interceptors数组中
                 */
                .config(['$httpProvider', function ($httpProvider) {
                    $httpProvider.interceptors.push('NickInterceptor');
                }])
                .controller('bodyCtl', ['$scope', '$http', function ($scope, $http) {
                    $scope.test1 = function () {
                        console.log(11);
                        $http.get('interceptors.html');
                    };
                }])

    </script>
</head>
<body ng-controller="bodyCtl">
<button class="btn" ng-click="test1()">click me</button>
<div ng-view></div>
</body>
</html>

  

 

转载于:https://www.cnblogs.com/puyongsong/p/6636462.html

<think>嗯,用户问的是Angular的响应拦截器,我需要先回忆一下相关的知识。首先,响应拦截器属于HTTP拦截器的一部分,对吧?Angular拦截器分为请求和响应两种,这里用户关注的是响应拦截器。 我应该先解释什么是响应拦截器,它的作用是什么。比如,它可以全局处理HTTP响应,修改数据或者错误处理。用户可能想知道怎么使用它,所以需要给出步骤。 然后,可能需要分点说明它的应用场景,比如统一错误处理、数据转换、添加日志等等。每个场景举一个例子,这样用户更容易理解。 接下来,用户可能需要具体的代码示例,来展示如何实现一个响应拦截器。这时候要注意代码的结构,比如实现HttpInterceptor接口,使用intercept方法,处理response.pipe。还要提醒他们需要在模块中提供这个拦截器,否则无法生效。 另外,要注意可能出现的常见问题,比如多个拦截器的执行顺序,或者修改响应体时的克隆操作。这些细节用户可能会遇到问题,需要提前说明。 还有,用户可能对拦截器的原理不太清楚,是否需要简单提一下Angular的HTTPClient模块和拦截器的工作流程?不过可能保持简洁更好,重点放在使用和示例上。 需要检查是否需要区分请求和响应拦截器的不同,但用户只问了响应,可能不用展开请求的部分,除非对比能帮助理解。 最后,确保语言口语化,避免太技术化的术语,但作为技术文档,适当的术语是必要的。结构要清晰,分步骤和应用场景,代码示例正确,符合Angular的最佳实践。 可能还需要提醒错误处理的时候,比如检查HTTP状态码,抛出错误或者转换错误格式。这在实际开发中很常见,用户会需要这些信息。 总之,整理出一个结构:定义、作用、实现步骤、应用场景、示例代码、注意事项。这样用户能逐步了解响应拦截器,并且有例子可以参考。</think>Angular 响应拦截器(Response Interceptor)是 Angular HTTP 客户端中用于全局拦截和处理 HTTP 响应的工具。它允许你在响应到达订阅者之前统一修改响应数据、处理错误或添加全局逻辑。以下是逐步解析: --- ### 一、核心作用 1. **统一错误处理**:自动捕获 HTTP 错误(如 404、500)并转换为友好提示。 2. **数据转换**:标准化后端返回的数据格式(如解包嵌套结构)。 3. **添加全局逻辑**:例如自动刷新令牌、日志记录、加载状态管理等。 4. **修改响应内容**:过滤敏感信息或补充字段。 --- ### 二、实现步骤 #### 1. 创建拦截器类 实现 `HttpInterceptor` 接口,并重写 `intercept` 方法: ```typescript import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class ResponseInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe( tap({ next: (event) => { // 成功响应处理 console.log('响应成功:', event); }, error: (err) => { // 错误处理 console.error('响应错误:', err); throw this.handleError(err); } }) ); } private handleError(error: any): string { // 统一错误格式 return error.status === 404 ? '资源不存在' : '服务器错误'; } } ``` #### 2. 注册拦截器 在模块的 `providers` 数组中提供拦截器: ```typescript import { HTTP_INTERCEPTORS } from '@angular/common/http'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: ResponseInterceptor, multi: true // 允许多个拦截器共存 } ] }) export class AppModule {} ``` --- ### 三、典型应用场景 #### 1. 统一解包响应体 若后端返回数据格式为 `{ code: 200, data: T, message: string }`,可提取 `data` 字段: ```typescript tap((event) => { if (event instanceof HttpResponse) { return event.clone({ body: event.body.data }); } }) ``` #### 2. 自动刷新令牌 当检测到 `401 Unauthorized` 时,尝试刷新令牌并重试请求(需配合 `retry` 操作符)。 #### 3. 全局加载状态控制 在拦截器中触发加载动画的显示/隐藏逻辑。 --- ### 四、注意事项 1. **执行顺序**:拦截器按注册顺序**反向**执行响应拦截(类似中间件栈)。 2. **不可变对象**:修改请求或响应时需克隆对象(如 `req.clone()`)。 3. **错误传播**:若未在拦截器中处理错误,需重新抛出(`throwError`)以保证订阅者能捕获。 --- ### 五、完整示例代码 ```typescript import { HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { tap } from 'rxjs/operators'; export class ApiWrapperInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { return next.handle(req).pipe( tap({ next: (event) => { if (event instanceof HttpResponse && event.status === 200) { // 标准化成功响应 const wrappedData = { ...event.body, timestamp: Date.now() }; return event.clone({ body: wrappedData }); } }, error: (err: HttpErrorResponse) => { // 统一错误格式 const userMessage = err.status === 401 ? '请重新登录' : '服务不可用'; throw new Error(userMessage); } }) ); } } ``` --- 通过响应拦截器,你可以显著减少重复代码,提升应用的可维护性和健壮性。实际开发中建议结合具体业务需求设计拦截逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值