我有一个我无法理解的怪异问题。我希望有一个人可以帮助我。
柱塞: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/