0

情况:我正在开发一个从单个页面加载和一个主模块运行的设备应用程序。应用程序通过两个 API 调用进行通信。应用程序需要从通过 POST 发送的对“/api/login”的 API 调用获取的当前身份验证状态。用于保存和填充视图渲染数据的 API 调用通过通过 POST 发送到“/api”的 API 调用进行通信。两次调用都是针对相同的协议://域:端口。

问题:仅在 IE9 中,Chrome 和 FF 正常工作,返回的数据对于“/api”的第二次 API 调用无效。在 IE9 中,开发人员工具网络面板显示正在调用“/api”,并带有所有假定的参数。但是,响应显示失败响应,就好像我仍在使用无效参数调用登录 api。

即使我将 $http.post 配置为在两个调用中立即过期并且缓存在两个调用中都设置为 false,这怎么可能?我该如何修复它或解决它?下面是我正在使用的代码。

编辑:忘了提到我是在 Windows 7 ThinkPad 上查看的。

index.js 中的代码:

var LocalPortal = angular.module('LocalPortal', ['ngResource'])
.value('lpApi', {
_apiList : [],
_apiUri : '/api',
_functionStack : {},
_host : document.location.hostname,
_port : 8080,
_protocol : document.location.protocol,
_sessionTimeout : 900,
_addToCallStack : function(param) {
  this._functionStack = $.extend(this._functionStack, param);
},
_doApiCall : function(dataSegment, command, params) {
  var segment = {};
  segment[dataSegment] = {"command" : command};
  if (params) {
    segment[dataSegment]["params"] = params;
  }
  this._addToCallStack(segment);
  $.subscribe('api.received', function(e,data) {
    $.publish(command, data[dataSegment]);
  });
},
_restoreAuthState : function() {
  var _authState = (sessionStorage.getItem('lpApi.authState')) ? JSON.parse(sessionStorage.getItem('lpApi.authState')) : {};
  lpApi.authState = _authState;
},
_setAuthTime : function(timeVal) {
  lpApi.authState.authTime = timeVal;
  lpApi._storeAuthState();
},
_storeAuthState : function() {
  sessionStorage.setItem('lpApi.authState', JSON.stringify(lpApi.authState));
},
_url : function() {
  return this._protocol + '//'
          + this._host +
          (this._port ? ':' + this._port : '')
  + this._apiUri;
},
apiList : function() {
  this._doApiCall("apiList", "api.list");
  return this;
},
getPayload : function() {
  var payload = this._functionStack;
  this._functionStack = {};
  return payload;
},
getUrl : function(uriExt) {
  return this._url() + uriExt;
},
init : function(){
  var loc = document.location;

  this._apiList = sessionStorage.getItem('apiList');
  this._host = loc.hostname;
  this._port = loc.port;
  this._protocol = loc.protocol;

  //store a reference to this object for later callbacks to access
  window.lpApi = this;

  //restore authentication state if any
  lpApi._restoreAuthState();
},
logOff : function() {
  lpApi._setAuthTime(0);
  sessionStorage.removeItem('lpApi.authState');
}
})
.config(function($routeProvider) {
$routeProvider.
  when('/login', {templateUrl: 'partials/login.html', controller: LoginCtrl}).
  when('/home', {templateUrl: 'partials/gateway.html', controller: GatewayCtrl}).
  when('/gateway', {templateUrl: 'partials/gateway.html', controller: GatewayCtrl}).
  when('/assets', {templateUrl: 'partials/assets.html', controller: AssetsCtrl}).
  when('/connectivity', {templateUrl: 'partials/connectivity.html', controller: ConnectivityCtrl}).
  when('/events', {templateUrl: 'partials/events.html', controller: EventsCtrl}).
  otherwise({redirectTo:'/home', templateUrl: 'partials/gateway.html', controller: GatewayCtrl});
for (var that in this) {
  if (that.substr(-4) == 'Ctrl') {
    if (this[that].prototype.menu) {
      for (var index in this[that].prototype.menu.items) {
        $routeProvider.
          when(this[that].prototype.menu.items[index].href, {
            templateUrl: this[that].prototype.menu.items[index].template,
            controller: that
          });
      }
    }
    if (this[that].prototype.ctrlActions) {
      for (var index in this[that].prototype.ctrlActions.items) {
        $routeProvider.
          when(this[that].prototype.ctrlActions.items[index].href, {
            templateUrl: this[that].prototype.ctrlActions.items[index].template,
            controller: that
          });
      }
    }
    if (this[that].prototype.mainActions) {
      for (var index in this[that].prototype.mainActions.items) {
        $routeProvider.
          when(this[that].prototype.mainActions.items[index].href, {
            templateUrl: this[that].prototype.mainActions.items[index].template,
            controller: that
          });
      }
    }

    if (this[that].prototype.secondaryActions) {
      for (var index in this[that].prototype.secondaryActions.items) {
        $routeProvider.
          when(this[that].prototype.secondaryActions.items[index].href, {
            templateUrl: this[that].prototype.secondaryActions.items[index].template,
            controller: that
          });
      }
    }
  }
}
})
.directive('appTopMenu', function() {
return {
  restrict: 'E',
  templateUrl: 'partials/top-menu.html'
}
})
.directive('appMenu', function() {
return {
  restrict: 'E',
  templateUrl: 'partials/menu.html',
  link: function(scope,element,attr) {
    for (var that in this) {
      if (that.substr(-4) == 'Ctrl') {
        if (this[that].prototype.menu) {
          for (var index in this[that].prototype.menu.items) {
            scope.menu.items[scope.menu.items.length] = this[that].prototype.menu.items[index];
          }
        }
      }
    }
  }
}
})
.run(function(){
});

var IndexCtrl = function($scope, lpApi, $location) {
//Properties
$scope._localPortalContainer = 'container';

$scope._loggedIn = true;

//Functions
$scope.assertAuthentication = function() {
if(!$scope.isAuthenticated()){
  lpApi.logOff();
  $scope.setRouteReload('/login');
}
};

$scope.getLocalPortalContainer = function() {
return $scope._localPortalContainer;
};

$scope.getLoggedInStatus = function() {
return $scope._loggedIn;
};

$scope.isAuthenticated = function() {
if (sessionStorage) {
  if (sessionStorage.getItem('lpApi.authState')) {
    lpApi.init();
    return ((new Date().getTime() - lpApi.authState.authTime) < 900000);
  }
  else {
    lpApi.init();
    return false;
  }
}
return false;
};

$scope.setErrorMsg = function(msg) {
$scope.errorMsg = msg;
};

$scope.setLocalPortalContainer = function($container){
$scope._localPortalContainer = $container;
};

$scope.setLoggedInStatus = function(status) {
$scope._loggedIn = status;
};

$scope.setRoute = function($route) {
$location.path($route);
};

$scope.setRouteReload = function($route) {
$location.path($route);
document.location.reload();
};

if (!$scope.isAuthenticated()) {
$scope.setLocalPortalContainer('container-small');
$scope.setLoggedInStatus(false);
$scope.setRoute('/login');
}
};

IndexCtrl.$inject = ['$scope', 'lpApi', '$location'];

login.js 的代码:

var LoginCtrl = function($scope, $http, lpApi) {

// Functions
$scope.authenticate = function(username, password, $http){
var data = {auth: {username: username, password: password}};

$http.post(lpApi.getUrl('')+'/login', data, {cache: false, headers: {Expires: -1}})
  .error($scope.postError)
  .success($scope.setAuthState);
};

$scope.login = function($scope, lpApi) {
if($scope.isAuthenticated() && lpApi.logOff) {
  lpApi.logOff();
  $scope.setRouteReload('/login');
}
$scope.setLocalPortalContainer('container-small');
$scope.setLoggedInStatus(false);
};

$scope.postError = function(data, status, headers, config){
// output error message
$scope.setErrorMsg(data.errorMessage[0])
};

$scope.setAuthState = function(data, status, headers, config){
lpApi.authState.sessionId = data.sessionId || null;
lpApi.authState.roles = data.roles || null;
lpApi.authState.requirePasswordChange = data.requirePasswordChange || null;
lpApi.authState.success = data.success;
if (data.success) {
  lpApi._setAuthTime(new Date().getTime());
  $scope.setLocalPortalContainer('container');
  $scope.setLoggedInStatus(true);
  $scope.setRoute('/home');
}
else {
  // output error message
  $scope.setErrorMsg(data.errorMessage[0])
}
};

$scope.submit = function(){
$scope.authenticate(this.input_username, this.input_password, $http);
};

$scope.login($scope, lpApi);
};

LoginCtrl.$inject = ['$scope', '$http', 'lpApi'];

gateway.js 的代码:

var GatewayCtrl = function($scope, lpApi, $http) {
lpApi.cloudlinkInfo();

lpApi.loggingQuery({limit:"5",page:"0"});

lpApi.modemInfo();

lpApi.osInfo();

lpApi.systemNodeinfo();

lpApi.systemProductinfo();

lpApi.tunnelInfo();

// Properties
$scope.loadData = function(data, status, headers, config) {
console.log('succes'); 
console.log(JSON.stringify(data)); // {"success":false,"errorMessage":["Invalid authentication."]} (See config url is not "/api/login")
console.log(status);
console.log(headers);
console.log(JSON.stringify(config)); // {"method":"POST","url":"protocol://domain:port/api","data":{"cloudlinkInfo": {"command":"cloudlink.info"},"loggingQuery" "command":"logging.query","params":{"limit":"5","page":"0"}},"modemInfo": "command":"modem.info"},"osInfo":{"command":"os.info"},"systemNodeinfo": "command":"system.nodeinfo"},"systemProductinfo" : {"command":"system.productinfo"},"tunnelInfo":{"command":"tunnel.info"}}}
};

$scope.postError = function(data, status, headers, config) {
console.log('error');
console.log(JSON.stringify(data));
console.log(status);
console.log(headers);
console.log(JSON.stringify(config));
};

$scope.assertAuthentication(); // <== asserts we have a current authState.

var payload = lpApi.getPayload(), apiUrl = lpApi.getUrl(''); // <== payload is an object of api calls and their params, apiUrl is protocol://domain:port/api

$http.post(apiUrl, payload).error($scope.postError).success($scope.loadData);
};

GatewayCtrl.$inject = ['$scope', 'lpApi', '$http'];
4

1 回答 1

0

“无效身份验证”响应实际上是一个有效响应。事实证明,根据 IE9 的预期,设备的 Web 服务设置的 cookie 是不完整的,而 IE9 完全忽略了它。Chrome 和 FF 更加宽容。

于 2012-06-28T17:38:46.993 回答