我有一个我无法理解的怪异问题。我希望有一个人可以帮助我。

柱塞:http://plnkr.co/edit/e9B6jc-由于某种原因,我无法在柱塞中重现这种情况,但是由于它已创建,因此将其留在此处以显示预期的设置和数据。

设置是这样的:


具有API的服务器。
服务器与带角度的Web界面。


过程是这样的:


我向API(/api/employees/{guid})发出GET请求,该请求返回数据(例如plunker中的employee.json)。我正在使用ngResouce(角度资源)来查询API。
它被HttpInterceptor拦截,后者向请求添加了一些必需的标头。
当服务器返回数据(服务器响应)时,该响应将再次被HttpInterceptor拦截。它会做一些事情,并根据状态拒绝或继续。
当它继续时,数据仅被传递回控制器。


我的问题在3到4之间:截获响应(3)后,我记录了数据(如插入器的script.js,第35行中所示),并且随机地将response.data.account.roles清空。我确定角色数组不是空的,因为当我检查开发人员工具(Google Chrome,“网络”标签)中的数据时,响应中包含所有数据。即使在API日志(在服务器端)中,角色数组也不为空。

奇怪的是,当我记录截获的响应时,response.data.account.roles可能为空(是的,并非总是如此)。但是,如果我明确记录了该对象(使用response.data.account.roles),则该数组永远不会为空。

在用户界面中,我使用angular来显示完整的对象(插件的index.html,第17行),有时account.roles为空。我之所以说有时候是因为它是在我重新加载页面时发生的。当然,这会在UI中引起问题,因为response.data.account.roles有时为空,我需要它来设置select元素的选定项。

我做了一些测试:


在angular-resource.js(执行响应的地方)中放置一个断点,response.data包含所有预期的角色。
在$ http(config).transformResponse(私有方法)中的angular.js中放置另一个断点,然后再次完成响应(不解析)(存在角色)。
在httpInterceptor内部,如果我对响应对象进行angular.copy,则将填充roles数组。

var copy = angular.copy(response);
// copy.data.account.roles.length > 0 = true
// response.data.account.roles.length > 0 = false



在前两个测试中,响应包含预期的数据,但奇怪的是,在UI(和拦截器)中,角色数组为空。

我希望有人能启发我,因为我无法弄清楚:(。顺便说一句,我也在Google网上论坛中问了这个问题-> https://groups.google.com/forum/#!topic/angular/ecJmyjBOvvc

感谢阅读本文的所有人。

插件代码是这样的:

script.js

var app = angular.module('app', ['ngResource']);

app.factory('HttpInterceptor', function($rootScope, $log, $q, $injector, $location) {
  var interceptor = {
    request: onRequest,
    requestError: onRequestError,
    response: onResponse,
    responseError: onResponseError
  };
  return interceptor;

  function onRequest(config) {
    $log.debug('Entering request.');
    config.headers['Accept-Language'] = 'es-cl';
    if (config.url.endsWith('.html')) {
      return config;
    }
    config.headers['Accept'] = 'application/json';
    var token = 'token data that comes from server';
    if (!angular.isUndefined(token)) {
      config.headers.Authorization = token;
    }
    $log.debug('Leaving request.');
    return config;
  }

  function onRequestError(error) {
    $log.error('Request failed.', error);
  }

  function onResponse(response) {
    $log.info('Response success.');
    // Roles array is empty
    // Here, when the account is present, the roles array MAY be empty
    $log.debug('Intercepted response data:', response);
    if (response) {
      if (response.data) {
        if (response.data.account) {
          // Data shown correctly
          // Here, when the account is present, the roles array ALWAYS has data
          // (of course, only when the roles is not empty)
          if (response.data.account.roles) {
            $log.debug('Roles:', response.data.account.roles);
          }
        }
      }
    }

    var copy = angular.copy(response);
    // copy.data.account.roles.length > 0 = true
    // response.data.account.roles > 0 = false (sometimes)

    return response || $q.when(response);
  }
});


mainController.js

angular.module('app').controller('mainCtrl', function($scope, $http, JsonFactory) {
  JsonFactory.get(function(data) {
    $scope.employee = data;
  });
});


jsonFactory.js

angular.module('app').factory('JsonFactory', function($resource) {
  return $resource('employee.json');
});


employee.json(预期的服务器响应)

{
  "id" : "employee-guid",
  "firstName" : "Test",
  "lastName" : "Subject",
  "nationalId" : "1-9",
  "account" : {
    "login" : "1-9",
    "email" : "a@a.com",
    "roles" : [
      {
        "id" : "role0-guid",
        "name" : "unpriv",
        "displayName" : "No permissions at all",
        "description" : "Some descriptive text"
      },
      {
        "id" : "role1-guid",
        "name" : "somepriv",
        "displayName" : "Some permissions",
        "description" : "Some descriptive text"
      }
    ]
  }
}


index.html

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
    <script src="https://code.angularjs.org/1.4.8/angular-resource.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <script src="jsonFactory.js"></script>
    <script src="mainController.js"></script>
  </head>

  <body ng-app="app">
    <div ng-controller="mainCtrl as ctrl">
      <div>
        <h4>Employee</h4>
        <pre>{{ employee | json }}</pre>
      </div>
      <div>
        <h4>Roles</h4>
        <pre>{{ employee.account.roles | json }}</pre>
      </div>
    </div>
  </body>

</html>


更新12-01-2016

copy.data.account.roles有时也可以为空。

我知道$log.debug|info|etc不会显示当前对象状态,因此我使用断点来检查Google Chrome中的对象。

角版本为1.4。

最佳答案

好吧,我解决了我的问题...问题是,我正在使用的指令正在删除数组的内容。

感谢所有花时间阅读本文的人。

关于javascript - 响应拦截器数据不完整,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34749214/

10-12 12:26
查看更多