AngularJS拦截所有$ http JSON响应

mat*_*sko 48 json interceptor angularjs

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

现在我有一个方法来首先检查JSON响应的内容,然后检查数据本身.

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

这工作,并且examineJSONResponse查看代码,如果有什么错误,它会抛出异常并使用window.location.href重新加载页面.

有没有什么方法可以在AngularJS中自动执行此操作,以便每次进行$ http调用时它会检查这个并且只返回数据变量内容作为JSON响应?

Glo*_*opy 91

您可以通过向$httpProvider.interceptorsAngular 1.1.4+ 添加拦截器来拦截响应(请参阅此处的文档搜索拦截器).

对于像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');
});
Run Code Online (Sandbox Code Playgroud)

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

也许有更好的方法,但我认为你可以使用http响应拦截器(这里描述)(对于像json这样的特定内容类型)执行与此帖相似的操作,即使调用成功,您也可能拒绝更改或抛出异常.您可以修改将传递给控制器​​代码的内容.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');
});
Run Code Online (Sandbox Code Playgroud)

  • 只是抬头:从1.1.4开始,响应拦截器已被弃用.有关替换,请参见[1.1.4 docs](http://code.angularjs.org/1.1.4/docs/api/ng.$http). (2认同)
  • @Kosmotaur感谢您的建议我已将1.1.4版本移至答案的底部. (2认同)

mat*_*sko 7

另一个解决方案是创建一个服务并使用$ 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);
      );
    }
}]);
Run Code Online (Sandbox Code Playgroud)

现在这可以称为:

myHttp(url, onSuccess, onFailure);
Run Code Online (Sandbox Code Playgroud)

  • 你的代码没有运行,因为`service`方法的第二个参数需要是一个构造函数,就像[AngularJS邮件列表中的这个帖子]中所解释的那样(https://groups.google.com/forum/#! MSG /角度/ 56sdORWEoqg/b8hdPskxZXsJ).我想你可能打算输入`factory`而不是`service`,这样可行. (2认同)