首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角-http-auth与$http transformResponse

角-http-auth与$http transformResponse
EN

Stack Overflow用户
提问于 2014-08-27 16:34:31
回答 2查看 2.1K关注 0票数 4

当从服务器返回401“未经授权”的响应时,我使用角-http-auth来显示登录对话框。

因为我很酷,所以我也尝试在我的服务中反序列化响应对象。例如,如果一个服务请求一个car,并且响应是{make: Honda, model: Civic},我尝试使用transformResponse将其反序列化为Car对象。

例如:

代码语言:javascript
复制
getCar: function() {
    return $http.get('/api/car', {
        method: 'GET',
        transformResponse: function(data, headers) {
            var c = angular.fromJson(data);
            return new Car(c);
        }
    });
}

这不适用于角-http-auth。如果响应是未经授权的401,您将得到一个javascript错误。这是因为,即使响应是401,角也会尝试运行该transformResponse代码。

事实证明,$http拦截器(这是角-http-auth使用的)是在transformResponse代码之后运行的。这是一个很大的问题,因为如果服务器响应是401 (不会有任何transformResponse ),那么transformResponse中的所有代码都不能工作。

这对其他人来说是个问题吗?你是怎么逃出来的?如果我使用transformResponse拦截器,我不使用$http吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-26 23:49:04

我知道,派对很晚了,但对于像我一样从谷歌来这里的任何人(我还在相关问题上发表了这样的评论):

我还发现,响应拦截器在transformResponse方法之后运行会让人感到困惑。我向$http.defaults.transformResponse添加了一个方法。这里是文档中关于如何做到这一点的一个例子。

因此,如果您需要在transformResponse方法之前运行一个响应拦截器,则应该这样做:

代码语言:javascript
复制
'use strict';

angular.module('app')
  .run(function ($http) {
    $http.defaults.transformResponse.push(function (data, headers) {
      // do stuff here before the response transformation

      // Be sure to return `data` so that the next function in the queue can use it.
      // Your services won't load otherwise!
      return data;
    });
  });

如果您的服务或http调用没有自己的响应转换器,那么您现在就很好了。

如果您的服务确实有自己的transformResponse方法,它们实际上将覆盖所有默认的转换器(我在长时间阅读了文档之后发现了这一点),并且上面的代码将不会运行。

为了避免这种情况,您可以在文档中遵循这个例子

票数 4
EN

Stack Overflow用户

发布于 2014-08-30 18:01:58

为了解决这个问题,我不再使用transformResponse了。如果transformResponse在$http拦截器之前运行,我就不明白它的意义了。

为了使用角-http-auth并在服务中反序列化响应,您可以编写服务,以便它们首先执行HTTP,然后在回调函数中反序列化响应。

举个例子,下面是我如何在OP中对这个示例进行重组:

柱塞

代码语言:javascript
复制
services.factory('HttpCarService', function($resource, $q) {
  var resource = $resource('/api/car');

  return {

    getCar: function() {

      var deferred = $q.defer();
      var car = null;

      var successCallback = function(data, status, headers, config) {
        var c = angular.fromJson(data);
        car = new Car(c);
        deferred.resolve(car);
      };

      var errorCallback = function(data, status, headers, config) {
        deferred.reject("something wrong");
      };

      var result = resource.get(successCallback, errorCallback);
      return deferred.promise;
    }
  };

});

如果data是一个数组,这个模式也会工作。

$http拦截器将在执行任何回调方法之前运行。如果您的$resource需要url,您可以使getCar()函数接受一个配置对象作为参数,并在执行$resource.get()调用时传递必要的信息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25532536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档