【问题标题】:AngularJS Intercept all $http JSON responsesAngularJS 拦截所有 $http JSON 响应
【发布时间】:2012-08-11 00:17:06
【问题描述】:

我有一个使用 AngularJS 构建的应用程序和一个以 JSON 形式传递所有请求的服务器端后端。每个请求都包装在一个 JSON 容器中,该容器包含一个数据变量,其中包含特定于请求的数据。其他数据,用于在应用程序中保持状态和控制,检查错误和成功消息,并检查会话标志。所有这些其他变量都随每个请求一起提供,并且在数据变量之前首先检查。

现在我有一种方法可以先检查 JSON 响应的内容,然后再检查数据本身。

$http.get('something.json').success(function(response) {
   var data = examineJSONResponse(response);
   //do the data stuff
});

这可行,examineJSONResponse 会查看代码,如果有问题,它会抛出异常并使用 window.location.href 重新加载页面。

有什么方法可以让我在 AngularJS 中自动执行此操作,以便每次调用 $http 时都会对其进行检查并仅将数据变量内容作为 JSON 响应返回?

【问题讨论】:

    标签: json angularjs interceptor


    【解决方案1】:

    您可以通过使用 Angular 1.1.4+ 向 $httpProvider.interceptors 添加拦截器来拦截响应(请参阅文档 here 搜索拦截器)。

    对于像 json 这样的特定内容类型,即使调用成功,您也可能会拒绝更改或抛出异常。您也可以在此处修改response.data,它将传递给您的控制器代码:

    myModule.factory('myHttpInterceptor', function ($q) {
        return {
            response: function (response) {
                // do something on success
                if(response.headers()['content-type'] === "application/json; charset=utf-8"){
                    // Validate response, if not ok reject
                    var data = examineJSONResponse(response); // assumes this function is available
    
                    if(!data)
                        return $q.reject(response);
                }
                return response;
            },
            responseError: function (response) {
                // do something on error
                return $q.reject(response);
            }
        };
    });
    myModule.config(function ($httpProvider) {
        $httpProvider.interceptors.push('myHttpInterceptor');
    });
    

    注意:这是 1.1.4 之前版本的原始答案(responseInterceptors 已被 Angular 1.1.4 弃用):

    也许有更好的方法,但我认为您可以使用 http 响应拦截器(描述为 here)(针对 json 等特定内容类型)执行类似于 this post 的操作,您可能会拒绝更改或抛出异常尽管通话很成功。您也可以在此处修改response.data,它将传递给您的控制器代码。

    myModule.factory('myHttpInterceptor', function ($q) {
        return function (promise) {
            return promise.then(function (response) {
                // do something on success
                if(response.headers()['content-type'] === "application/json; charset=utf-8"){
                    // Validate response if not ok reject
                    var data = examineJSONResponse(response); // assumes this function is available
    
                    if(!data)
                        return $q.reject(response);
                }
                return response;
            }, function (response) {
                // do something on error
                return $q.reject(response);
            });
        };
    });
    myModule.config(function ($httpProvider) {
        $httpProvider.responseInterceptors.push('myHttpInterceptor');
    });
    

    【讨论】:

    • @MikeyCee 我修改了示例以包括注册拦截器。希望这会有所帮助!
    • 如何在我的 $http.get 请求中使用它?
    • 请注意:从 1.1.4 开始,响应拦截器已被弃用。替换请参见1.1.4 docs
    • @SwampDiner 感谢您的评论!我已经更新了代码 sn-p 以使用新的 1.1.4+ 样式。
    • @Kosmotaur 感谢我将 1.1.4 之前的版本移至答案底部的建议。
    【解决方案2】:

    另一个解决方案是创建一个服务并在 $http 变量周围使用它。

    angular.module('App', [])
      .factory('myHttp',['$http',function($http) {
        return function(url, success, failure) {
          $http.get(url).success(function(json) {
              var data = examineJSONResponse(json);
              data && data.success ? success() : failure();
            }).error(failure);
          );
        }
    }]);
    

    现在可以这样调用:

    myHttp(url, onSuccess, onFailure);
    

    【讨论】:

    • 您的代码无法运行,因为service 方法的第二个参数需要是构造函数,如this thread in the AngularJS mailing list 中所述。我想你可能打算输入factory 而不是service,这样就可以了。
    • 你是对的。它应该是factory。现在更新了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多