Ajaxアクセス時のセッションエラーの問題を完全に解決

亚连
リリース: 2018-05-23 17:28:29
オリジナル
3716 人が閲覧しました

今回は、Ajaxアクセス時のセッション失敗の問題を完全に解決する記事をお届けします。今からそれを皆さんと共有し、皆さんの参考にしてください。

最近、プロジェクトにより、モジュールが ajax リクエスト データに切り替わりました。セッションが失敗した場合、ajax リクエストの後に戻り値はなく、応答 html:

現在、Ajax は Web プロジェクトで広く使用されており、ほとんどどこでも いいえ、これでは別の疑問が生じます。Ajax リクエストでセッション タイムアウトが発生した場合はどうすればよいでしょうか?

明らかに、ここでは従来のページ ジャンプは適用できません。Ajax リクエストはブラウザーではなく XMLHTTPRequest オブジェクトによって開始され、サーバーが返す (または出力する) ため、検証が失敗した後のページ ジャンプはブラウザーに反映されません。情報はJavaScript(XMLHTTPRequestオブジェクト)で受信します。

それでは、この状況にどう対処すべきでしょうか?

メソッド

サーバーから返されたメッセージはXMLHTTPRequestオブジェクトによって受信され、XMLHTTPRequestオブジェクトはJavaScriptの制御下にあるため、JavaScriptを使用してページジャンプを完了できますか?

もちろんできます、そして、それは簡単です!ただし、HTTP リクエストが Ajax リクエストであるかどうかを判断する必要があることが 1 つあります (AJAX リクエストと通常のリクエストは別々に処理する必要があるため)。これはどのように判断するのでしょうか?実際、Ajax リクエストは通常​​の HTTP リクエストとは異なります。これは、以下に示すように、HTTP リクエストのヘッダー情報に反映されています。

前者は、Firefox の Firebug を使用して傍受されました。 HTTP リクエストのヘッダー情報。後者は Ajax リクエストのリクエスト ヘッダー情報です。最初の図の赤枠で囲った部分に注目してください。ここがAj​​axリクエストのヘッダーにX-Requested-Withの情報が含まれており、その値がXMLHttpRequestになっている点です。私たちはそれを活用することができます。

コードがどのように実装されるかを見てみましょう。

インターセプターフィルター

Struts2を使用する場合、通常、権限の問題をインターセプトするためにInterceptor(インターセプター)を使用します。

インターセプタ部分コード:

public String intercept(ActionInvocation invocation) throws Exception {
    // TODO Auto-generated method stub
    ActionContext ac = invocation.getInvocationContext();
    HttpServletRequest request = (HttpServletRequest) ac.get(StrutsStatics.HTTP_REQUEST);
    String requestType = request.getHeader("X-Requested-With");
    System.out.println("+++++++++++++++++++++++reqestType:"+requestType);
    HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
//    String basePath = request.getContextPath();
    String path = request.getContextPath(); 
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; 
    //获取session
    Map session = ac.getSession();
    //判断session是否存在及session中的user信息是否存在,如果存在不用拦截
    if(session != null && session.get(Constants.FE_SESSION_BG_USER) != null && session.get(Constants.FE_SESSION_BG_AUTH) != null){
      System.out.println(invocation.getProxy().getActionName()+"++++++++++++++++++++++++");
      System.out.println("namespace:"+invocation.getProxy().getNamespace());
      //访问路径
      String visitURL = invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + Constants.FE_STRUTS_ACTION_EXTENSION;
      visitURL = visitURL.substring(1);
      Map<String , Object> authMap = (Map<String, Object>) session.get(Constants.FE_SESSION_BG_AUTH);
      Map<Integer, String> actionMap = (Map<Integer, String>) authMap.get(Constants.FE_BG_ACTIONMAP);
      if(actionMap != null && !actionMap.isEmpty() && visitURL != null){
        if (actionMap.containsValue(visitURL)) {
          System.out.println(visitURL+"-----------------------");
          return invocation.invoke();
        } else{
          String forbidden = basePath + Constants.FE_BG_FORBIDDEN;
          response.sendRedirect(forbidden);
          return null;
        }
      }
      return invocation.invoke();
    }else{
      if(StringUtils.isNotBlank(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")){
        response.setHeader("sessionstatus", "timeout"); 
        response.sendError(518, "session timeout."); 
        return null;
      }else {
        
        String actionName = invocation.getProxy().getActionName();
        System.out.println(actionName);
        //如果拦截的actionName是loginUI或login,则不做处理,否则重定向到登录页面
        if (StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGINUI)) {
          return invocation.invoke();
        }else if(StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGIN)){
          return invocation.invoke();
        }else{
          String login = basePath + "/" + Constants.FE_BG_LOGIN_NAMESPACE + "/" + Constants.FE_BG_LOGINUI + Constants.FE_STRUTS_ACTION_EXTENSION;
//        System.out.println("+++++++++++++++++++++++++++basePath:"+basePath);
//        response.sendRedirect(login);
          PrintWriter out = response.getWriter();
//        out.println("<html>"); 
//        out.println("<script>"); 
//        out.println("window.open (&#39;"+login+"&#39;,&#39;_top&#39;);"); 
//        out.println("</script>"); 
//        out.println("</html>");
          out.write("<html><script type=&#39;text/javascript&#39;>window.open(&#39;"+login+"&#39;,&#39;_top&#39;);</script></html>");
          return null;
        }
      }
    }
    
  }
ログイン後にコピー

上記のコードからわかるように、セッション検証が失敗した場合(つまり、セッションがタイムアウトした場合)、リクエストヘッダ情報の値をX-Requested-With経由で取得します。 HttpServletRequest。これが空ではなく、XMLHttpRequest と等しい場合、このリクエストは Ajax リクエストであることを意味し、応答にヘッダー情報 (カスタマイズされた) が追加され、応答オブジェクト HttpServletResponse がサーバー エラー情報 (518) を返します。ステータスは独自に定義されます); この情報は JavaScript によって受信され、その後の処理は JavaScript コードによって実行されます。

Javascript コード

$.ajaxSetup メソッドは、AJAX リクエストのデフォルト オプションを設定するために使用されます。そのため、このコードは外部 JS ファイルで参照できます。必要なページ。

rreee

以上が皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。

関連記事:

Ajaxの内部値を外部から呼び出せない原因と解決策

Ajaxクロスドメインリクエストを回避するためにNginxリバースプロキシを使用する方法

Ajax総合アプリケーションの総合分析

以上がAjaxアクセス時のセッションエラーの問題を完全に解決の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート