[javascript] jQuery Ajax 호출 후 리디렉션 요청을 관리하는 방법

내가 사용하고 $.post()Ajax를 사용하여 서블릿을 호출 한 다음은 HTML 조각을 결과하는 것은 교체 사용하여 div사용자의 현재 페이지의 요소를. 그러나 세션 시간이 초과되면 서버는 리디렉션 지시문을 보내 사용자를 로그인 페이지로 보냅니다. 이 경우 jQuery는 div요소를 로그인 페이지의 내용으로 대체 하여 사용자의 눈이 드문 장면을 목격하게합니다.

jQuery 1.2.6을 사용하여 Ajax 호출에서 리디렉션 지시문을 관리하려면 어떻게해야합니까?



답변

이 질문을 읽고 브라우저가 리디렉션을 투명하게 처리하지 않도록 응답 HTTP 상태 코드 를 278로 설정하는 것과 관련하여 언급 된 접근 방식을 구현했습니다 . 이것이 효과가 있었지만 약간의 해킹이기 때문에 약간 불만족했습니다.

더 파고 들자, 나는이 접근법을 버리고 JSON을 사용했습니다 . 이 경우 AJAX 요청에 대한 모든 응답은 상태 코드 200을 가지며 응답 본문에는 서버에서 구성된 JSON 오브젝트가 포함됩니다. 그런 다음 클라이언트의 JavaScript는 JSON 객체를 사용하여 필요한 작업을 결정할 수 있습니다.

나는 당신과 비슷한 문제가있었습니다. 가능한 두 가지 응답이있는 AJAX 요청을 수행합니다. 하나 는 브라우저를 새 페이지로 리디렉션 하고 다른 하나 는 현재 페이지의 기존 HTML 양식을 새 페이지로 바꿉니다 . 이를 수행하는 jQuery 코드는 다음과 같습니다.

$.ajax({
    type: "POST",
    url: reqUrl,
    data: reqBody,
    dataType: "json",
    success: function(data, textStatus) {
        if (data.redirect) {
            // data.redirect contains the string URL to redirect to
            window.location.href = data.redirect;
        } else {
            // data.form contains the HTML for the replacement form
            $("#myform").replaceWith(data.form);
        }
    }
});

JSON 객체 “data”는 서버에서 2 개의 멤버 ( data.redirect및) 를 갖도록 구성됩니다 data.form. 나는이 접근법이 훨씬 더 낫다는 것을 알았습니다.


답변

이 문제를 다음과 같이 해결했습니다.

  1. 응답에 사용자 정의 헤더 추가 :

    public ActionResult Index(){
        if (!HttpContext.User.Identity.IsAuthenticated)
        {
            HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
        }
        return View();
    }
  2. JavaScript 함수를 ajaxSuccess이벤트에 바인딩 하고 헤더가 존재하는지 확인하십시오.

    $(document).ajaxSuccess(function(event, request, settings) {
        if (request.getResponseHeader('REQUIRES_AUTH') === '1') {
           window.location = '/';
        }
    });

답변

브라우저가 301 및 302 응답을 올바르게 처리하지 않습니다. 그리고 실제로이 표준은 Ajax Library 공급 업체에게는 큰 골칫거리 인 “투명하게”처리해야한다고 말합니다. 에서 RA-아약스 우리는 투명하게 처리하는 서버에서 리디렉션 할 HTTP 응답 상태 코드 278 (그냥 “사용되지 않는”성공 코드)를 사용하여 강제로했다 …

이것은 정말로 나를 귀찮게하며, 여기 누군가 W3C에 “풀”이 있으면 W3C에 301 및 302 코드를 직접 처리해야한다는 것을 W3C에 알릴 수 있음을 감사드립니다 …! 😉


답변

결국 구현 된 솔루션은 Ajax 호출의 콜백 함수에 랩퍼를 사용하고이 랩퍼에서 리턴 된 HTML 청크에 특정 요소가 있는지 확인하는 것입니다. 요소가 발견되면 랩퍼가 경로 재 지정을 실행했습니다. 그렇지 않은 경우 래퍼는 호출을 실제 콜백 함수로 전달했습니다.

예를 들어 래퍼 함수는 다음과 같습니다.

function cbWrapper(data, funct){
    if($("#myForm", data).length > 0)
        top.location.href="login.htm";//redirection
    else
        funct(data);
}

그런 다음 Ajax 호출을 할 때 다음과 같은 것을 사용했습니다.

$.post("myAjaxHandler",
       {
        param1: foo,
        param2: bar
       },
       function(data){
           cbWrapper(data, myActualCB);
       },
       "html"
);

이것은 모든 Ajax 호출이 항상 페이지의 일부를 교체하는 데 사용하는 DIV 요소 내에서 HTML을 반환했기 때문에 효과적이었습니다. 또한 로그인 페이지로 리디렉션하기 만하면됩니다.


답변

레몬이 약간 꼬인 Timmerz의 방법이 마음에 듭니다. 당신이 이제까지 반환받을 경우 의 contentType텍스트 / HTML을 당신이 예상 할 때 JSON을 , 당신이 가장 가능성이 리디렉션되고있다. 내 경우에는 단순히 페이지를 다시로드하면 로그인 페이지로 리디렉션됩니다. 아, 그리고 jqXHR 상태가 200인지 확인하십시오. 오류 기능에 있기 때문에 어리석은 것처럼 보입니다. 그렇지 않으면 합법적 인 오류 사례로 인해 반복적 인 재로드 (강제)가 발생합니다.

$.ajax(
   error:  function (jqXHR, timeout, message) {
    var contentType = jqXHR.getResponseHeader("Content-Type");
    if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
        // assume that our login has expired - reload our current page
        window.location.reload();
    }

});


답변

저수준 $.ajax()통화를 사용하십시오 .

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp is a XMLHttpRquest object
    alert(xmlHttp.status);
  }
});

리디렉션을 위해 이것을 시도하십시오 :

if (xmlHttp.code != 200) {
  top.location.href = '/some/other/page';
}


답변

누군가에게 도움이 될 수 있으므로 내 접근 방식을 공유하고 싶었습니다.

기본적으로 사용자 이름 표시와 같은 인증 항목을 처리하는 JavaScript 모듈과 로그인 페이지로리디렉션을 처리하는 JavaScript 모듈이 포함되었습니다 .

내 시나리오 : 우리는 기본적으로 모든 요청을 듣고 로그인 페이지 의 302와 위치 헤더응답 하는 ISA 서버를 가지고 있습니다 .

내 JavaScript 모듈에서 내 초기 접근 방식 은 다음과 같습니다.

$(document).ajaxComplete(function(e, xhr, settings){
    if(xhr.status === 302){
        //check for location header and redirect...
    }
});

문제는 (여기에서 이미 언급했듯이) 브라우저가 내 ajaxComplete콜백이 호출되지 않은 자체 리디렉션을 처리 하지만 대신 이미 리디렉션 된 로그인 페이지응답을 얻었습니다 . 분명히했다 status 200. 문제 : 성공적인 200 응답이 실제 로그인 페이지인지 아니면 다른 임의의 페이지인지 어떻게 감지합니까?

해결책

302 리디렉션 응답을 캡처 할 수 없으므로 LoginPage로그인 페이지 자체의 URL이 포함 된 헤더를 로그인 페이지에 추가했습니다 . 모듈에서 이제 헤더를 듣고 리디렉션을 수행합니다.

if(xhr.status === 200){
    var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage");
    if(loginPageRedirectHeader && loginPageRedirectHeader !== ""){
        window.location.replace(loginPageRedirectHeader);
    }
}

… 그리고 그것은 매력처럼 작동합니다 :). 왜 LoginPage헤더에 URL을 포함시키는 지 궁금 할 것입니다 … 기본적으로 객체 GET에서 자동 위치 리디렉션으로 인한 URL을 결정하는 방법을 찾지 못했기 때문에 xhr