웹 프로그래밍

사파리에서 발생하는 ajax와 XHR의 에러콜백

728x90
반응형

문제상황: 사파리브라우저에서 대회공모전 탭으로 이동시 XHR의 에러콜백이 발생하는 것을 확인하였다. 이는 대회공모전 신규생성시 붉은 점으로 표시되는 기능을 구현하기위해 만들어둔 manageNotification()에서 발생한 것이었다.

원인을 요약하자면 a tag에 ajax를 호출하는 것이 좋은 행동이 아니라고한다. 일부 브라우저는 이것을 막기도하는데 사파리 브라우저가 그 일부브라우저인것같다. 해결후 글을 추가하겠다.

 

https://okky.kr/article/897149

 

OKKY | safari ajax요청의 문제

버튼 클릭 이벤트시 $.ajax 비동기 데이터요청을 할때  request가 되고 에러를 반환하지만 데이터는 제대로 저장됩니다 하지만 사파리브라우저에서만 success 콜백이나오지않고 error 콜백이 반환되

okky.kr

//대회 및 공모전 알림 user_has_seen 체크
function manageNotification(checkNotificationURL) {
    const csrftoken = getCookie('csrftoken');
    let xmlhttp = new XMLHttpRequest();

    xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == XMLHttpRequest.DONE) {
			if (xmlhttp.status != 200) {
				alert('알수없는 에러(3)가 발생했습니다. 지속된다면 to.devdreamer@gmail.com로 문의해주세요.');
			}
		}
	};

	xmlhttp.open("DELETE", checkNotificationURL, true);
	xmlhttp.setRequestHeader("X-CSRFToken", csrftoken);
	xmlhttp.send();
}
<a href="{% url 'contest:list' %}"
            style="{% if '/contest/' in request.path %}color:#F07489;border-bottom:2px solid;{% endif %}"
            class="{% if contest_notify %}notify-circle{% endif %}"
            onclick="manageNotification(`{% url 'notificationapp:contest-notify-check'%}`)">
    대회 및 공모전
</a>

해결을 위해 a 태그안에 div를 씌워 그 안에 onclick을 줘보기도 했는데 단순히 a태그라 안된다기 보단 페이지 이동시에 일어나는 비동기통신을 차단한 것 같다.  

 

어떻게 해결할 것인가

a태그 onclick을 빼고 ajax.js파일은 항상 불러오도록 되어있으니 그 안에서 window.location.pathname를 받아 조건문으로 /contest/안에서는 manageNotification(checkNotificationURL)을 실행시키라는 코드를 만들어주면 될 것 같다. 해보고 이어 작성하겠다.

 

$(document).ready(function(){
    //대회 및 공모전 알림 user_has_seen 체크 작동
    if (window.location.pathname==='/contest/') {
        manageNotification(checkNotificationURL);
    }
});
<a href="{% url 'contest:list' %}"
            style="{% if '/contest/' in request.path %}color:#F07489;border-bottom:2px solid;{% endif %}"
            class="{% if contest_notify %}notify-circle{% endif %}">
    대회 및 공모전
</a>

<script type="text/javascript">
    const checkNotificationURL = "{% url 'notificationapp:contest-notify-check'%}"
</script>

onclick을 없앴고 /contest/아래에서 실행되는 코드를 만들었다. 한가지 이슈가 있었는데

Javascript에서 django url template tag를 사용할 수가 없는 문제였다. 우선은 템플릿안에 스크립트태그를 만들어 거기서 전역변수를 만들고 전달해주었더니 작동하였다. 예쁘진않은데 우선은 이렇게 사용해야할 것 같다.

 

728x90
반응형