>  기사  >  웹 프론트엔드  >  Ajax 접속시 Session failure 문제를 완벽하게 해결

Ajax 접속시 Session failure 문제를 완벽하게 해결

亚连
亚连원래의
2018-05-23 17:28:293662검색

아래에서는 Ajax 접속 중 세션 실패 문제를 완벽하게 해결한 글을 소개해 드리겠습니다. 이제 그것을 여러분과 공유하고 모든 사람에게 참고 자료로 제공하겠습니다.

최근 프로젝트로 인해 모듈이 ajax 요청 데이터로 전환되었습니다. 세션이 실패하면 ajax 요청 후 반환 값이 없고 응답 html: 100db36a723c770d327fc0aef2ce13b19564dd7b4cc38b9939d91ba21008aabcwindow.open ('http://192.168.0.118:8080/welcomeAction/loginUI.do','_top');2cacc6d41bbb37262a98f745aa00fbf073a6ac4ed44ffec12cee46588e518a5e

이제 Ajax는 웹 프로젝트에서 널리 사용됩니다. 거의 모든 곳에서 아니요. 이는 또 다른 질문을 불러일으킵니다. Ajax 요청에서 세션 시간 초과가 발생하면 어떻게 해야 합니까?

Ajax 요청은 브라우저가 아닌 XMLHTTPRequest 객체에 의해 시작되기 때문에 분명히 전통적인 페이지 점프는 더 이상 적용되지 않습니다. 서버가 반환(또는 출력)하기 때문에 확인 실패 후 페이지 점프가 브라우저에 반영될 수 없습니다. 정보는 JavaScript(XMLHTTPRequest 객체)에 의해 수신됩니다.

그렇다면 우리는 이 상황에 어떻게 대처해야 할까요?

Method

서버에서 반환된 메시지는 XMLHTTPRequest 객체로 수신되고, XMLHTTPRequest 객체는 JavaScript의 제어를 받기 때문에 JavaScript를 사용하여 페이지 점프를 완료할 수 있나요?

물론 가능하고 쉽습니다! 하지만 한 가지 중요한 점은 HTTP 요청이 Ajax 요청인지 확인해야 한다는 것입니다(AJAX 요청과 일반 요청을 별도로 처리해야 하기 때문에). 이를 어떻게 확인하나요? 실제로 Ajax 요청은 일반적인 HTTP 요청과 다릅니다. 이는 아래와 같이 HTTP 요청의 헤더 정보에 반영됩니다.

위 두 그림은 Firefox의 Firebug를 사용하여 가로채는 것입니다. HTTP 요청 헤더 정보. 후자는 Ajax 요청의 요청 헤더 정보입니다. 첫 번째 그림에서 빨간색 상자로 둘러싸인 부분에 주목하세요. Ajax 요청 헤더에는 X-Requested-With 정보가 포함되어 있으며 그 값은 XMLHttpRequest입니다. 우리는 활용할 수 있습니다.

코드가 어떻게 구현되는지 살펴보겠습니다.

Interceptor filter

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;
        }
      }
    }
    
  }

위 코드에서 알 수 있듯이 Session 검증이 실패(즉, Session Time Out)되면 요청 헤더 정보 X-Requested-With의 값을 다음을 통해 얻습니다. HttpServletRequest가 비어 있지 않고 XMLHttpRequest와 같다면 이는 이 요청이 Ajax 요청임을 의미합니다. 우리의 응답은 응답에 헤더 정보(사용자 정의)를 추가하고 응답 객체 HttpServletResponse가 서버 오류 정보(518)를 반환하도록 하는 것입니다. 상태는 우리가 임의로 정의합니다.) 이 정보는 JavaScript에 의해 수신되며 다음 작업은 JavaScript 코드에 의해 수행됩니다.

Javascript 코드

$.ajaxSetup 메소드는 AJAX 요청에 대한 기본 옵션을 설정하는 데 사용되므로 이 코드는 외부 JS 파일에서 언급되고 참조될 수 있습니다. 필수 페이지.

/**
 * 设置未来(全局)的AJAX请求默认选项
 * 主要设置了AJAX请求遇到Session过期的情况
 */
$.ajaxSetup({
  type: &#39;POST&#39;,
  complete: function(xhr,status) {
    var sessionStatus = xhr.getResponseHeader(&#39;sessionstatus&#39;);
    if(sessionStatus == &#39;timeout&#39;) {
      var top = getTopWinow();
      var yes = confirm(&#39;由于您长时间没有操作, session已过期, 请重新登录.&#39;);
      if (yes) {
        top.location.href = &#39;/skynk/index.html&#39;;      
      }
    }
  }
});
/**
 * 在页面中任何嵌套层次的窗口中获取顶层窗口
 * @return 当前页面的顶层窗口对象
 */
function getTopWinow(){
  var p = window;
  while(p != p.parent){
    p = p.parent;
  }
  return p;
}

위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.

관련 기사:

Ajax 내부 값을 외부에서 호출할 수 없는 이유와 해결 방법

Nginx 역방향 프록시를 사용하여 Ajax 도메인 간 요청을 방지하는 방법

Ajax 종합 애플리케이션 종합 분석

위 내용은 Ajax 접속시 Session failure 문제를 완벽하게 해결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.