今回は、Sessionへの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 リクエストのリクエスト ヘッダー情報です。最初の図の赤枠で囲った部分に注目してください。ここがAjaxリクエストのヘッダーにX-Requested-Withの情報が含まれており、その値がXMLHttpRequestになっている点です。私たちはそれを活用することができます。
コードがどのように実装されるかを見てみましょう。
InterceptorFilter
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 ('"+login+"','_top');"); // out.println("</script>"); // out.println("</html>"); out.write("<html><script type='text/javascript'>window.open('"+login+"','_top');</script></html>"); return null; } } } }
上記のコードからわかるように、セッション検証が失敗した場合(つまり、セッションがタイムアウトした場合)、リクエストヘッダ情報の値をX-Requested-With経由で取得します。 HttpServletRequest。空ではなく、XMLHttpRequest と等しい場合、このリクエストは Ajax リクエストであることを意味し、ヘッダー情報を応答に追加し、応答オブジェクト HttpServletResponse をサーバーに返します。 エラー メッセージ。 (518 ステータスは独自に定義します); この情報は JavaScript で受け取られるため、以下の作業は JavaScript コードによって行われます。
Javascript コード
$.ajaxSetup メソッドは、AJAX リクエストのデフォルト オプションを設定するために使用されます。そのため、このコードは外部 JS ファイルで参照できます。必要なページ。
/** * 设置未来(全局)的AJAX请求默认选项 * 主要设置了AJAX请求遇到Session过期的情况 */ $.ajaxSetup({ type: 'POST', complete: function(xhr,status) { var sessionStatus = xhr.getResponseHeader('sessionstatus'); if(sessionStatus == 'timeout') { var top = getTopWinow(); var yes = confirm('由于您长时间没有操作, session已过期, 请重新登录.'); if (yes) { top.location.href = '/skynk/index.html'; } } } }); /** * 在页面中任何嵌套层次的窗口中获取顶层窗口 * @return 当前页面的顶层窗口对象 */ function getTopWinow(){ var p = window; while(p != p.parent){ p = p.parent; } return p; }
この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。
推奨読書:
Ajax はプログレスバー効果を備えたファイルアップロードを実装します
以上がajax がアクセスしたときにセッション障害を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。