web-dev-qa-db-ja.com

anglejs $ httpでリダイレクトを処理する

アプリでanglejs httpサービスを使用しています。 website でこれに気づきました

AJAX呼び出しが成功した場合(サーバーが200〜209のHTTPコードを送り返す)、success()関数に渡された関数が実行されます。 AJAX呼び出しが失敗した場合(リダイレクトを除く他のすべてのコード)、error()メソッドに渡された関数が実行されます。

明らかに、リダイレクトステータスコードはエラーコールバックでも成功の一部でもありません。では、リダイレクトをどのように処理するのでしょうか?

これは私のスクリプトが行うことで、http getを使用してサーバーからデータを取得します。セッションの有効期限が切れると、サーバーは302ステータスコードを返します。そのステータスコードをキャッチして、ページをログインにリダイレクトする必要があります。

app.controller('GraphController', function($scope, $http, localStorageService, $interval) {
        $scope.GraphData = [{"key":"in","values":[]},{"key":"out","values":[]}]; 

        $scope.pollStats = function() {
            $http.get('/statistics/getStat').success(function(lastData, status, headers) {              
                if (status==302) {
                    //this doesn't work
                    //window.location=headers('Location');
                    //this doesn't work either
                    window.location.replace(headers('Location'));
                }else if (status==200) {
                    ...processData
                }
            });
        };
});

成功コールバックがリダイレクトを処理できないため、明らかに私のスクリプトは機能しません。では、どのように処理するのでしょうか?

20
user3714598

これは私のプロジェクトに固有のものであることに注意してください。

目標:302ステータスコードをキャッチし、ページをリダイレクトします(私の場合はログインします)。

結果:firebugでは、応答コードが302であることがわかりましたが、ステータス(response.status)の値を出力するだけで、angularjsが200を返すことがわかりました。だから、最初はあなたは絶望的だと思っていました。しかし、私の場合、私がやったのはデータ(response.data)を取得することでした。ログインページでしか見つからない文字列を探してください。それで終わりです。問題解決:D

ここでアイデアが取り入れられました。

ここにコードがあります

app.factory('redirectInterceptor', function($q,$location,$window){
    return  {
        'response':function(response){
        if (typeof response.data === 'string' && response.data.indexOf("My Login Page")>-1) {
            console.log("LOGIN!!");
            console.log(response.data);
            $window.location.href = "/login.html";
            return $q.reject(response);
        }else{
            return response;
        }
        }
    }

    });

    app.config(['$httpProvider',function($httpProvider) {
        $httpProvider.interceptors.Push('redirectInterceptor');
    }]); 
31
user3714598

ログインリダイレクトにはhttpインターセプターよりも良い方法があると思います。リクエストレスポンスを解析し、別のページにリクエストされた文字列がある場合、エラーが発生するからです。

サービスで$ httpメソッドをラップし、リクエストを行う前にユーザーがログインしているかどうかを確認することをお勧めします。

app.service('httpWrapper', ['$http','requestLogin',function($http,requestLogin){
  var httpWrapper = {};

  // You can add methods for put, post
  httpWrapper.get = function(url){
    // Before making the request, check with a request if the user is logged
    $http.get(urlLogged).success(function (auth) {
        if(!auth.logged){
            // Show login widget
            requestLogin.show();
        }
    }).error(function(){

    });        
    return $http.get(url);
  }

  return httpWrapper;
}]);

次に、他のサービスで$ httpの代わりにhttpWrapperを使用します。

app.service('otherService', ['httpWrapper',function(httpWrapper){
  httpWrapper.get(url);
}]);

ここでrequestLoginのサービス:

app.service('requestLogin', ['$rootScope',function($rootScope){
  var requestLogin = {};

  $rootScope.showlogin = false;

  requestLogin.show = function(){
    $rootScope.showlogin = true;
  }

  requestLogin.hide = function(){
    $rootScope.showlogin = false;
  }    
  return requestLogin;
}]);

そして、あなたの見解では:

<div ng-show="showlogin == true">
  Please log-in...
</div>
1
Gautier Drusch

私もこの問題にぶつかり、初めてログインするときに、ユーザーにパスワードを変更するよう促すプロンプトを表示するニースの方法を見つけようとしました。

この問題を解決する方法は、UIルーターの状態プロバイダーに必要な情報を含むロケーションヘッダー付きの(非公式の)210ステータスコードをサーバーに返すことです。前面のコントローラーに以下を追加しました:

if (data.status == 210) {
  var location = data.headers().location;
  $state.go(location);
} else {
  $state.go("user", {name: data.data.fullName, userId: data.data.userId});
}
1
Albert Waninge