2013-04-28 2 views
2

단일 페이지 ASP.NET MVC 3 애플리케이션을 개발 중입니다. 모든 게시물은 ajax 전화로 처리됩니다. 사용자는 페이지의 거의 모든 것을 볼 수 있지만 일부 작업은 사용자가 로그인해야합니다. 사용자가 로그인하지 않은 경우 전 세계 필터 ajax 성공 핸들러

액션이 로그인을 필요로하는 경우

, 나는 JSON {unauthenticated: true}를 반환 내가 좋아하는 몇 가지 성공 처리기 그래서 :.

success : function(response){ 
    if(response.unauthenticated){ 
    showLoginDialog(); 
    } else { 
    doTheActualWork(); 
    } 
} 

내가 세계 success 핸들러에서 그것을 할 싶어합니다. 마찬가지로 :

$(document).ajaxSuccess(function (event, XMLHttpRequest, ajaxOptions){ 
    if(unauthenticated()){ 
    preventTheLocalSuccess(); 
    showLoginDialog(); 
    } 
}); 

그리고 지역의 성공 핸들러가 될 것입니다 :

success: function(response){ 
    // No Checking 
    doTheActualWork(); 
} 

그렇게 할 수있는 방법이 있나요?

+0

그들은 단지 코드를 검사하고'doTheActualWork()'수동으로 실행하면 어떻게? – Johan

답변

2

대신 JSON이 올바른 HTTP 오류 코드 (이 경우 401 Unauthorized)를 반환합니다. 그런 다음 ajaxError 메서드를 사용하여 처리 할 수 ​​있습니다.

$(document).ajaxError(function (event, XMLHttpRequest, ajaxOptions){ 
    switch (xhr.status) { 
     case 401: // Unauthorized 
      // Take action, referencing xhr.responseText as needed. 
      showLoginDialog(); 
      return false; 
      break; 
     } 
}); 

또한 ajaxError 조건을 확장하여 다른 실패한 요청을 처리 할 수 ​​있습니다.

+0

그런 식으로 작동하지 않습니다. '.ajaxSuccess'는 모든 지역 성공 핸들러가 해고 된 후에 핸들러를 시작합니다. 따라서'.ajaxSuccess'를 막을 수는 없습니다. 또한 핸들러에 지정된 이벤트 객체에는'preventDefault'도 없습니다. – Joseph

+0

@JosephtheDreamer 감사합니다. 답변을 업데이트했습니다. – Brombomb

+0

응답하기 전에 코드를 테스트하십시오. 내가 말했듯이, [글로벌 핸들러는 로컬 핸들러를 따라 발사합니다. 그런 식으로 로컬 처리기를 멈출 수 없습니다.] (http://jsfiddle.net/7366L/1/) – Joseph

3

dataFilter property of $.ajax을 살펴 봐야합니다. 이 속성은 요청을받은 직후 핸들러가 실행되기 전에 실행되는 함수를 허용합니다. 이것의 주요 목적은 jQuery 자체로 처리되기 전에 수신 된 데이터를 전처리하는 것입니다. 따라서 데이터를 받게됩니다. 로그인과 같은 중간 프로세스를 수행 할 수 있습니다.

이 구성을 모든 Ajax 호출에 적용하려면 $.ajaxSetup을 사용하여 모든 Ajax 요청에 대해 dataFilter을 미리 정의하십시오. 따라서 각 Ajax 요청에는 로컬 핸들러가 실행되기 전에 dataFilter 핸들러가 실행됩니다. 샘플 코드에 관해서는

, here's a demo, which pretty much works as expected :

function login() { 
    console.log('login initiated: you are not logged in'); 
} 

$.ajaxSetup({ 
    dataFilter: function (origdata, type) { 

     //the type is determined by the type you indicated in the ajax call 
     //if not json, we return the data unharmed 
     if (type !== 'json') return origdata; 

     //data filter receives the raw response. since we have determined it's json 
     //we parse it using jQuery's parseJSON to check the contents 
     var data = $.parseJSON(origdata); 

     if (data.auth) { 
      //if logged in, we just return the data 
      return origdata; 
     } else { 
      //otherwise, we execute the login 
      //since returning something is required, we return false so local handler 
      //data checks will fail against the false data 
      login(); 
      return false; 
     } 
    } 
}); 

//the url and data passed is for jsFiddle to work. 

//logged in 
$.post('/echo/json/', { 
    json: JSON.stringify({ 
     auth: true 
    }) 
}, function (data) { 
    //in our handler, it's your normal "check data before use" 
    //if data is truthy, it skips this check and moves on 
    if(!data) return; 
    console.log('data retrieved successfully', data); 
}, 'json'); 

//not logged in 
$.post('/echo/json/', { 
    json: JSON.stringify({ 
     auth: false 
    }) 
}, function (data) { 
    //since we returned false, the code stops at this check 
    if (!data) return; 
    console.log('you should not see this since data is false, per dataFilter return', data); 
}, 'json'); 
+0

이 방법은 정상적으로 작동합니다. 한가지 문제. 내 요청에'dataType' 옵션을 지정해야합니다. 지능형 추측은 작동하지 않습니다. 그것에 대한 도움이 필요하십니까? – Mohayemin

+0

@Mohayemin 그것은'dataFilter'가 데이터를 받기 전에 * jQuery가 데이터에 닿기 때문입니다. jQuery는 유형을 지능적으로 추측하기 위해 데이터를 처리하지 않았습니다. – Joseph

+0

흠, 알아. 즉, 다른 방법을 확인해야한다는 뜻입니다. – Mohayemin