2018년 1월 25일 목요일

ajax 동기화 처리하기

동기화가 필요한 코드

아래의 코드는 ajax를 통해 로그인 여부 확인 후 로그인이 안된 경우 dwg 확장명을 가진 파일이 다운로드 안되도록 하는 코드이다. 실제 다운로드시 서버 단에서 한번 더 체크하는 부분은 별도로 있다.


수정전

아래처럼 작성한 경우 비동기 처리되어 로그인 여부 확인이 뒤늦게 이루어져서 "다운로드 권한이 없습니다." 라는 메시지가 의도한 대로 잘 작동되지 않는다.



/**
 * 로그온 여부 확인
 * @returns {Boolean}
 */
function isLogon() {
    //데이터 요청
    $.ajax({
        url : contextPath+'/main/isLogon.ajax',
        type : 'POST',
        dataType : 'json',
        contentType : 'application/json; charset=UTF-8',
        success : function(result) {
            //console.log("result : "+JSON.stringify(result));
            //console.log("basicInfoList : "+result.basicInfoList.length);
            return result;
        },
        error : function(request,status,error) {
            console.log("code:"+request.status+"\n\n"+ "message:" + request.responseText + "\n\n"+"error:"+error);
            //alert($(request.responseText.replace(/(\r\n|\n|\r)/gm,"")).text());
            //alert("처리에 실패하였습니다.\ncode:"+request.status+"\n"+"error:"+error);
        },
        complete : function() {
        }
    });
}

$(document).ready(function() {
    /**
     * 파일 다운로드 처리
     */
    $(document).on('click', '.down', function(){
        //로그인 시에만 다운로드 처리
        var ext = ($(this).text().split("."));
        //로그인 여부와 확장자 확인하는 부분
        if (isLogon() == false && ext[ext.length-1].toLowerCase() == "dwg") {
            //로그인이 안되었고 확장자가 dwg라면
            alert("다운로드 권한이 없습니다.");
        } else {
            var fileSn = $(this).data("filesn");
            var seq = $(this).data("seq");
            window.open(contextPath+"/main/filedown.do?seq="+seq+"&fileSn="+fileSn);
        }
    });
});


그래서 $.ajax(); 의 async 속성 사용으로 뭔가 방법을 찾을수 있을까 생각 했지만 async는 deprecated 되었다고 한다. async : false로 설정시 아래의 오류가 발생하였다.

파이어폭스에서... 메인 쓰레드에서의 동기화된 XMLHttpRequest는 사용자 경험에 안좋은 영향을 미치기 때문에 더이상 사용하지 않습니다. 더 자세한 사항은 http://xhr.spec.whatwg.org/ 를 참고해 주십시오.

크롬에서... [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.


수정후

이번엔 조금 다른 병식을 찾아서 적용해 보았다. 이번엔 의도한 대로 작동이 잘 되었다.



/**
 * 로그온 여부 확인
 * @returns {Boolean}
 */
function isLogon() {
    //데이터 요청
    var pormise = $.ajax({
        url : contextPath+'/main/isLogon.ajax',
        type : 'POST',
        //data : JSON.stringify(data),
        //async : false, //deprecated
        dataType : 'json',
        contentType : 'application/json; charset=UTF-8',
        success : function(result) {
            //console.log("result : "+JSON.stringify(result));
            //console.log("basicInfoList : "+result.basicInfoList.length);
        },
        error : function(request,status,error) {
            //console.log("code:" + request.status+"\n\n" + "message:" + request.responseText + "\n\n"+"error:"+error);
            //alert($(request.responseText.replace(/(\r\n|\n|\r)/gm,"")).text());
            //alert("처리에 실패하였습니다.\ncode:"+request.status+"\n"+"error:"+error);
        },
        complete : function() {
        }
    });
 
    return pormise;
}

$(document).ready(function() {
    /**
     * 파일 다운로드 처리
     */
    $(document).on('click', '.down', function(){
        var ext = ($(this).text().split("."));
        var fileSn = $(this).data("filesn");
        var seq = $(this).data("seq");
        var pormise = isLogon();
        var sessionOn = false;

        //jqXHR.done(function( data, textStatus, jqXHR ) {});
        //jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
        //jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { });
        
        pormise.done(function(result){
            sessionOn = result;
            //console.log(result);
         
            //로그인 여부와 확장자 확인하는 부분
            if (sessionOn == false && ext[ext.length-1].toLowerCase() == "dwg") {
                //로그인이 안되었고 확장자가 dwg라면
                alert("다운로드 권한이 없습니다.");
            } else {
                window.open(contextPath+"/main/filedown.do?seq=" + seq + "&fileSn=" + fileSn);
            }
        });
        //pomise.fail(function(){ ... }); //아직 테스트 못해봄
        //pomise.always(function(){ ... }); //아직 테스트 못해봄
    });
});