状況: 1 つのページの読み込みとメイン モジュールから実行されるデバイス アプリケーションを開発しています。アプリケーションは、2 つの API 呼び出しを介して通信します。アプリケーションは、POST 経由で送信された「/api/login」への API 呼び出しから取得された現在の認証状態を必要とします。ビュー レンダリングのデータを保存および設定するために使用される API 呼び出しは、POST 経由で「/api」に送信される API 呼び出しによって伝達されます。どちらの呼び出しも、同じ protocol://domain:port に対して行われます。
問題: IE9 のみで、Chrome と FF が期待どおりに動作し、返されたデータが "/api" への 2 番目の 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'];