아이포니앙
아이폰, 아이패드, 터치 소모임입니다.
잡담 사파리 뒤로가기가 안 되는 오류 🐕 짜증나네요 3
마음에평화를
1,607
2022-04-15 20:03:25 223.♡.30.101
아이폰으로 사파리 하다가 보면 가끔 갑자기 뒤로가기가 안되는 경우가 뜨는 현상 때문에 짜증나네요 구글링 해봐도 딱히 뾰족한 수는 없고.. 천하의 애플이 이런 오류 하나도 못 잡고 있다는게 참..
마음에평화를 님의 게시글 댓글
0명
댓글 • [3]
을 클릭하면 간단한 회원메모를 할 수 있습니다. 메모동기화
아내의유혹
1 2 3 4 5
LINK
#134426968
IP 61.♡.134.234
22-04-15 2022-04-15 20:13:23
·
임시방편으로 아이클라우드 사파리 동기화를 끄면 됩니다..
언제 고쳐줄런지 ㅠㅠ
밥먹어요
1 2 3 4 5
LINK
#134429441
IP 219.♡.139.149
22-04-15 2022-04-15 22:37:41
·
탭그룹 없애면 해결된다는 것 같습니다. 저도 없앴더니 괜찮아졋어요
마음에평화를
1 2 3 4 5
LINK
#134441035
IP 211.♡.114.244
22-04-16 2022-04-16 20:09:00
·
@밥먹어요님 탭그룹 때문에 사파리 쓰는 건데 ㅠㅠ 아쉽네요
목록으로
글쓰기
[Javascript] IOS 웹뷰 뒤로가기 자바스크립트 오류(IOS History Back Error)
안녕하세요. 갓대희 입니다. 이번 포스팅은 [ [Javascript] 아이폰 뒤로가기 오류(IOS History Back Error) ] 입니다. : )
0.들어가기 앞서
Safari, Firefox 브라우저에서, 나와 같은 경우 아이폰 웹뷰 Safari의 경우에
BFCache 때문에 페이지 개발 방식에 따라 뒤로가기시 스크립트 로드가 되지 않아 정상 동작하지 않는 경우가 있다.
별 의미 없지만 문득, 이런 오류를 겪을수 있는 확률? 가능성?이 얼마나 되는지 확인해 보고 싶었다. 다음 모바일 브라우저의 사용 통계 데이터를 확인해보자.
1) 전 세계 기준
- 크롬이 약 65% 점유율로 단연 앞서며, 사파리가 약 25%로 한 축을 이루고 있다.
뒤이어 삼성 갤럭시의 힘을 받아 삼성 인터넷 브라우저가 뒤를 이어 가고 있는 모습이다.
2) 한국 기준
-크롬이 약 40% 점유율, 삼성 26%, 사파리가 약 20%로 결국 최소 20% 이상은 Safari를 사용하고 있는 것이다.
1. 오류 현상
- 상기 브라우저(IOS 웹뷰 등)에서 뒤로가기기 자바스크립트가 실행되지 않는 경우.
ex) 뒤로가기시 BFCache로 동작하였기 때문에 네트워크 요청도 없고, Page Load시의 페이지를 만드는 스크립트 동작도 이루어지지 않는 경우.
2. BFCach(Back-Forward Cache)
- 해당 현상의 원인은 BF Cache 때문이다.
아이폰(IOS) Safari 브라우저에서 뒤로가기(history.back) 또는 동일 페이지 등으로 이동하는 경우 BF Cache를 사용한다.
- BFCache란 동일 세션내 브라우저에서 이전 페이지를 보다 빠르게 로딩하기 위해 이전에 저장한 캐싱된 페이지를 바로 로드하는 방법이라고 할 수 있을것 같다.
참고 : developer.mozilla.org/en-US/docs/Archive/Misc_top_level/Working_with_BFCache
- 장점 : 미리 저장한, 즉 캐싱된 페이지를 그대로 사용하기 때문에 페이지 응답 속도, 즉 속도적인 측면에서 유리하다. 이 캐싱 상태는 브라우저를 닫을 때까지 유지된다.
- 단점 : window.onload, $(document).ready()와 같은 onLoad 이벤트가 동작하지 않기 때문에 개발자의 의도와 다른 페이지를 보여줄 수 있다.
좀더 자세한 내용은 위 참고 url을 확인 해보자.
3. 뒤로가기 오류 해결 방안.
- 다음 가이드에 따라 2가지 가능한 방법을 확인할 수 있었다.
developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching
※ 해결 방안
▶ 3.1 pagehide / pageshow 사용, persisted 속성 사용
- 위 가이드에서 확인해보면 pageshow/pagehide 이벤트를 대안으로 제시하고 있다.
- 파이어 폭스와 같은 경우 2009년 부로 pagehide / pageshow 이벤트가 생겼고(현재 물론 safari에서도 정상 동작) 해당 이벤트에 대해 알아 보자.
(bugs.webkit.org/show_bug.cgi?id=28758)
1) pageshow 함수 : load 이벤트에 대응
2) pagehide 함수 : unload 이벤트에 대응
3) persisted 속성
- window.onpageshow(onpagehide)함수의 event 파라미터에서 event.persisted를 통해 BForward Cache를 이용해서 호출되었을 경우 true, 아닌경우 false를 리턴 한다.
4) window.performance.navigation 객체 사용
- 혹시나 event.persisted가 동작하지 않는 경우를 대비하여 추가 하였다.
- window.performance.navigation 객체는 리다이렉트(redirect), 앞/뒤 버튼, 혹은 보통의 URL 로딩이 어떤 페이지 로드를 일으키는지(trigger) 등의 확인에 사용할 수 있는 속성을 갖고 있다.
- window.performance.navigation.type = 2 인경우 History 이동을 의미 한다.
※ 참고
0(TYPE_NAVIGATENEXT) : 링크 클릭, 직접 입력, Form
submit 등의 네비게이션
1(TYPE_RELOAD) : 리로드(reload) 또는 location.reload() 메소드를 통한 내비게이션
2(TYPE_BACK_FORWARD) : 히스토리 이동(순회) 연산을 통한 내비게이션
3(TYPE_UNDEFINED) : 위의 경우에 벗어난 네비게이션
5) 사용 예시
- 해당 함수에 ios 또는 특정 브라우저 일때만 핸들링 하는 부분을 추가하여 사용하면 될 것 같다. 나와 같은 경우는 ios webview인경우 reload 처리
물론 reload하기 때문에 화면 깜빡임 현상이 발생하였고, 페이지 캐시 효과는 없어 졌지만 당장 BFCache 로인한 에러는 해결 하였다.
ex1) 일반적인 사용 예
window.onpageshow = function(event){ if ( event.persisted || (window.performance && window.performance.navigation.type == 2) ){ alert("BFCache를 통해 페이지 접근!"); } };ex2) 일반적인 사용 예2
<body onpageshow="if( event.persisted || (window.performance && window.performance.navigation.type == 2) ) alert("BFCache를 통해 페이지 접근!");">ex3) 화살표 함수 사용
- (//goddaehee.tistory.com/228) 참고
window.onpageshow = (event) => { if ( event.persisted || (window.performance && window.performance.navigation.type == 2) ){ alert("BFCache를 통해 페이지 접근!"); } };ex4) jQuery 사용시
$(window).bind("pageshow", function(event) { if ( event.persisted || (window.performance && window.performance.navigation.type == 2) ){ alert("BFCache를 통해 페이지 접근!"); } });▶ 3.2 No Cache 처리
- developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching
- 상기 내용을 확인해보면 Cache처리가 안되는 몇가지 케이스가 있는데 해당 케이스처럼 만들어 주면 캐시 처리가 안되지만, 캐싱처리를 해야하는 내용까지 캐싱처리가 안될 수 있으니 조심 해야 할 것 같다.
**************** 내용 참고 ****************
ㆍthe page uses an unload or beforeunload handler;
ㆍthe page sets "cache-control: no-store".
ㆍthe site is HTTPS and page sets at least one of:
- "Cache-Control: no-cache"
- "Pragma: no-cache"
- with "Expires: 0" or "Expires" with a date value in the past relative to the value of the "Date" header (unless "Cache-Control: max-age=" is also specified);
ㆍthe page is not completely loaded when the user navigates away from it or has pending network requests for other reasons (e.g. XMLHttpRequest));
ㆍthe page has running IndexedDB transactions;
ㆍthe top-level page contains frames (e.g. <iframe>) that are not cacheable for any of the reasons listed here;
ㆍthe page is in a frame and the user loads a new page within that frame (in this case, when the user navigates away from the page, the content that was last loaded into the frames is what is cached).
****************************************
ex1) 사용 예시
@RequestMapping("/test.test") public ModelAndView test(HttpServletRequest request, HttpServletResponse response,{ response.setHeader("Expires", "일자"); response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); response.setHeader("Pragma", "no-cache"); }나와 같은 경우는 당연히 속도 이슈도 그렇고, 리로드 하는 방법으로 해결 하였다.
이왕 이렇게 된 것 뒤로가기와 관련된 내용을 다음 포스팅으로 이어 나가도록 해야 겠다.