사파리,파이어폭스등 브라우저 뒤로가기시
스크립트 리로드 오류 처리( onpageshow / BFCache )
모바일 웹(Hybrid App 등) 개발을 하다보면 OS / 브라우저의 특성에 따른 생각지 못한 이슈가 많이 발생 합니다.
저는 주로 확장프로그램이 다양한 크롬 브라우저를 이용해 디버깅 하고 있는데 이번에 담당하고 있는 시스템에서 아이폰 (IOS) 사파리 브라우저에서 뒤로가기(history.back / 디바이스 뒤로가기 동일)했을때 페이지가 리로드 되지 않고 스크립트가 정상적으로 실행되지 않는 증상이 발생하여 관련 자료를 정리합니다.
원인 - BFCache
"뒤로가기" 액션이 있었을 때 각 브라우저 엔진(크롬,익스,사파리,파이어폭스 등)마다 동작하는 로직이 조금씩 다르게 구성되어 있습니다.
사파리,파이어폭스(Safari, Flrefox) 브라우저에서는 동일 세션에서 이전 페이지를 빠르게 보다 로딩하기 위하여 BFCache( Back-Foward-Cache ) 기능을 이용하여 이전에 저장한(캐싱) 데이터를 바로 로드하고 있는데요.
( Firefox1.5 브라우저에서 bfcache 사용 상세 내용 )
이때 Javascript 상태값까지 모두 저장된 값으로 재사용하게 되는데 서버단(jsp,asp)에서 데이터 처리 및 화면 구성이 끝나는 페이지 구성일 경우에는 이러한 데이터 재사용이 문제가 되지 않지만 window.onload 나 Jquery의 $(document).ready() 단계에서 Ajax를 통하여 로그인이나 주요 화면처리하는 로직이 들어있는 구성인 경우에는 BFCache를 통해 이전 데이터를 불러오는 것은 이슈가 될 수 있습니다.
저의 경우도 반응을 빠르게 하기 위해 페이지 구성 로직을 서버단에서 최소화 한뒤 $(document).ready() 단계에서 AJAX를 사용하여 rest API를 통해 불러온 데이터들을 핸들링하여 대부분의 화면 로직 처리되게끔되어 있는 구조라 문제가 됐던 케이스입니다.
해결 - onpageshow 이벤트
이를 해결하기 위한 방법으로 페이지가 로드될때마다 무조건 발생하는 onpageshow 이벤트를 사용하였습니다.
onpageshow 이벤트는 onload 이벤트와 비슷하지만 onload 이벤트는 페이지가 캐시에서 로드될때는 발생하지 않는 이벤트인 반면에 onpageshow 이벤트는 페이지가 로드 될때마다 무조건 발생하는 이벤트입니다.
onpageshow 이벤트에 함수를 바인딩 하고 함수내에서 페이지가 캐시(BFCache)되었는지 알아 보기 위하여 persisted 속성을 사용하는데 이 속성은 페이지가 캐시되었을 경우(뒤로가기) true를, 아닐 경우 false를 반환 합니다.
그리고 true값을 리턴 받았을 경우 강제로 페이지를 리로드하여 데이터를 재조회 할 수 있게끔 처리해 주시면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //HTML <body onpageshow="Init()"> function Init() { window.location.reload(); } //Javascript window.onpageshow = function(event) { // BFCahe if (event.persisted) { window.location.reload(); }else{} //새로운페이지 } //Jquery $(window).bind("pageshow", function(event) { if ( event.originalEvent && event.originalEvent.persisted) {// BFCahe window.location.reload(); }else{}//새로운페이지 }); | cs |
onpageshow 이벤트 자세히보기 (w3schools.com)