티스토리 뷰

실무 이슈

크롬 beforeunload 이벤트 XHR Sync 정책

알 수 없는 사용자 2020. 5. 10. 20:42

교육 관련 업종 회사에서 근무 중인 나는 간헐적으로 학습에 대한 진도가 누적되지 않는다는 요청을 받았다.

교육 서비스를 제공하는 만큼 진도누적에 대한 이슈는 꽤나 크리티컬 하고 중요한데
진도를 누적하는 방법이 학습자가 어떤 과목을 학습하냐, 혹은 어떤 환경에서 학습하냐 (모바일, 웹) 등에 따라 달라지고,
또한 기업을 상대로 서비스를 제공하는 경우가 많다보니 기업별로 커스텀이 걸려있는 경우가 많기 때문에
워낙 경우의 수가 많고, 복잡하여 이미 적용된 진도누적방식을 수정하거나 건드릴 일은 거의 없었다.

그럼에도 불구하고 진도 누적에 대한 오류가 나왔다는 것은 대개 운영자가 과목에 대한 세팅을 잘못하였거나, 개발자가 실수로 쿼리나 코드를 잘못 고치거나 배포했을 경우가 대부분이기 때문에, 나의 처음 접근 방법은 과목에 대한 세팅을 파악하는 것이었다.

하지만..
과목에 대한 셋팅과 진도 누적 방식에 대한 변경점은 찾을 수 없었고, 결국 로컬에서 같은 환경을 만들어 테스트해보기 시작했다.
다행히도(?) 테스트 환경에서도 진도가 누적되지 않는 것이다.
테스트 환경에서 안된다는 것은 디버깅을 통해 원인을 접근할 수 있지만, 정상적으로 진도를 쌓은 학습자도 있었기 때문에 혼란스러웠다.

일단 간헐적으로 안된다는 점과 로컬에서도 안된다는 점을 미루어 봤을 때, 브라우저 환경에 따른 변수를 생각했고,
결과적으로 크롬에서만 진도누적이 안 되는 것을 찾았다.

원인은..
브라우저를 강제로 종료할 때 진도누적 API를 ajax를 동기방식으로 호출하여 누적시키는 방식이었는데, 크롬에서 beforeunload 이벤트 발생 시에 정책을 변경한 것이었다.

 

beforeunload 이벤트에서 ajax 동기방식 호출 시 에러

위 이미지처럼 기존에 흔히 사용하던 XMLHttpRequest 동기방식으로 요청하면 위와 같은 에러가 발생한다.

(창이 닫힐 때 발생하는 부분이라 처음에 이 에러를 캐치하는데 시간이 오래 걸렸다 -_-)

해당 현상에 대해 검색해보니.. 크롬 정책에 관한 글을 볼 수 있었고,

결과적으로 크롬에서 해당 기능을 막은 것 이었다.

 

크롬 beforeunload XMLHttpRequest 요청 정책 : https://www.chromestatus.com/feature/4664843055398912 

 

Disallow sync XHR in page dismissal - Chrome Platform Status

Synchronous XHR is on the deprecation path. It hurts the end user experience. beforeunload and unload are used by third parties and first parties to send analytics data to servers. While this is reasonable, there are no good reasons to use synchronous XHR.

www.chromestatus.com

 

정책상 브라우저에서 막았으니 개발자로서의 방법을 이를 우회하여 사용하거나, 다른 방식으로 접근할 수 있는 방법을 찾아야 했다.

 

대안이 될 수 있는 방법으로 두 가지 정도 찾았는데

첫 번째 방법은 navigator.sendBeacon(url, data)을 사용하는 방법이다.

실제로 작동되는 것을 확인은 했지만.. 이 방식은 리턴 값이 응답 결과가 아닌 응답의 성공 유무(?)로 true, false만 리턴되는 것 같다.

 

두 번째 방법은 클라이언트에서 해당 기능을 사용할 수 있게 풀어주는 것이다.

https://topazsystems.com/software/chromeallowsyncxhrinpagedismissalguide.pdf

위 링크에 들어가면 클라이언트에서 설정을 하여 해당 기능을 사용할 수 있도록 할 수 있다.

하지만 서비스하는 입장에서 클라이언트에게 해당 방법을 유도하는 건 굉장히 비효율적, 사실상 불가능한 방법이다.

 

사실, 진도 누적을 비동기로 요청했어야만 했던 이유는 진도 누적한 후에 학습자의 현재 총 학습시간으로 알럿트를 띄워줘야 했기 때문에,

sendBeacon 방식은 사용하지 못했고, 결국 동기방식으로 일단 진도 저장을 하는 방식으로 전환했다.

 

다음 글에서는 위에서 말한 알럿에 관한 이슈는 어떤 게 있었는지 남겨볼 것이다. 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함