加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs http拦截器类(ES6)失去了对“this”的约束

发布时间:2020-12-17 07:42:37 所属栏目:安全 来源:网络整理
导读:我正在建筑和AngularJS应用程序使用ES6类与痕迹扩散到ES5的AMD格式. 在我的模块中,我导入拦截器类并将其注册为服务,然后使用module.config中的$httpProvider.interceptors注册此服务: var commonModule = angular.module(moduleName,[constants.name]);impo
我正在建筑和AngularJS应用程序使用ES6类与痕迹扩散到ES5的AMD格式.

在我的模块中,我导入拦截器类并将其注册为服务,然后使用module.config中的$httpProvider.interceptors注册此服务:

var commonModule = angular.module(moduleName,[constants.name]);

import authenticationInterceptor from './authentication/authentication.interceptor';

commonModule.service('authenticationInterceptor',authenticationInterceptor);

commonModule.config( $httpProvider =>  {
    $httpProvider.interceptors.push('authenticationInterceptor');
});

我的拦截器类注入$q和$window服务,将它们保存在构造函数中供以后使用.我使用调试器跟随这部分,注入正常进行:

'use strict';
/*jshint esnext: true */

var authenticationInterceptor = class AuthenticationInterceptor {

    /* ngInject */
    constructor($q,$window) {
        this.$q = $q;
        this.$window = $window;
    }

    responseError(rejection) {
        var authToken = rejection.config.headers.Authorization;
        if (rejection.status === 401 && !authToken) {
            let authentication_url = rejection.data.errors[0].data.authenticationUrl;
            this.$window.location.replace(authentication_url);
            return this.$q.defer(rejection);
        }
        return this.$q.reject(rejections);
    }
}

authenticationInterceptor.$inject = ['$q','$window'];

export default authenticationInterceptor;

当我发出一个响应401的请求时,拦截器触发器相应地触发,但是在’responseError’方法中,’this’变量指向窗口对象而不是我的拦截器,所以我没有访问权限$q或这一点.$窗口.

我不知道为什么?有任何想法吗?

上下文(this)将丢失,因为Angular框架只保留对处理函数本身的引用,并直接调用它们,而没有任何上下文,如 alexpods所指出的.

我最近写了一篇关于使用TypeScript编写$http拦截器的博文,这也适用于ES6类:AngularJS 1.x Interceptors Using TypeScript.

为了总结我在这篇文章中讨论过的内容,为了不在你的处理程序中丢失,你必须将方法定义为箭头函数,有效地将函数直接放在编译的ES5代码中的类的构造函数中.

class AuthenticationInterceptor {

    /* ngInject */
    constructor($q,$window) {
        this.$q = $q;
        this.$window = $window;
    }

    responseError = (rejection) => {
        var authToken = rejection.config.headers.Authorization;
        if (rejection.status === 401 && !authToken) {
            let authentication_url = rejection.data.errors[0].data.authenticationUrl;
            this.$window.location.replace(authentication_url);
            return this.$q.defer(rejection);
        }
        return this.$q.reject(rejections);
    }
}

如果你真的坚持把拦截器写成一个完全基于原型的类,你可以为拦截器定义一个基类并扩展它.基类将用实例方法替换原型拦截器函数,所以我们可以这样编写我们的拦截器:

class HttpInterceptor {
  constructor() {
    ['request','requestError','response','responseError']
        .forEach((method) => {
          if(this[method]) {
            this[method] = this[method].bind(this);
          }
        });
  }
}

class AuthenticationInterceptor extends HttpInterceptor {

    /* ngInject */
    constructor($q,$window) {
        super();
        this.$q = $q;
        this.$window = $window;
    }

    responseError(rejection) {
        var authToken = rejection.config.headers.Authorization;
        if (rejection.status === 401 && !authToken) {
            let authentication_url = rejection.data.errors[0].data.authenticationUrl;
            this.$window.location.replace(authentication_url);
            return this.$q.defer(rejection);
        }
        return this.$q.reject(rejections);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读