Ajax가 세션에 액세스할 때 세션 실패를 처리하는 방법

php中世界最好的语言
풀어 주다: 2018-04-04 13:51:08
원래의
1478명이 탐색했습니다.

이번에는 Session에 대한 Ajax 접근 실패를 처리하는 방법을 보여 드리겠습니다. Ajax Session 접근 실패를 처리할 때 주의 사항은 무엇입니까? 다음은 실제 사례입니다.

최근 프로젝트로 인해 모듈이 ajax 요청 데이터로 전환되었습니다. 세션이 실패했을 때 ajax 요청 후 반환 값이 없었고 응답 html:

이제 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입니다. 우리는 활용할 수 있습니다.

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

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=&#39;text/javascript&#39;>window.open('"+login+"','_top');</script></html>");
          return null;
        }
      }
    }
    
  }
로그인 후 복사

위 코드에서 알 수 있듯이 Session 검증이 실패(즉, Session Time Out)되면 요청 헤더 정보 X-Requested-With의 값을 다음을 통해 얻습니다. HttpServletRequest가 비어 있지 않고 XMLHttpRequest와 같다면 이는 이 요청이 Ajax 요청임을 의미합니다. 우리의 응답은 응답에 헤더 정보(맞춤형)를 추가하고 응답 객체 HttpServletResponse를 서버에 반환하는 것입니다. 오류 메시지 (518 상태는 저희가 임의로 정의한 것입니다.) 이 정보는 자바스크립트로 받아오기 때문에 다음 작업은 자바스크립트 코드로 하게 됩니다.

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 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

Ajax는 진행률 표시줄 효과로 파일 업로드를 구현합니다.

Ajax ToolKit으로 등급 제어를 사용하는 방법

위 내용은 Ajax가 세션에 액세스할 때 세션 실패를 처리하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!