Iframe 이 있는 페이지에서 뒤로가기 실행시 비정상으로 동작하는 경우

화면 개발시에 iframe은 계륵 같은 존재라고 생각한다.

css 를 분리하고 유지/보수 를 따로 할수 있으므로. ( 또한 배포도..)
서비스에는 상당히 유용하지만.  실제 서비스에 활용했을때는 생각보다 이슈가 많이 발생한다.

이 이슈도 개발인 서비스에서 부득이하게 iframe을 사용했을때 발생했던 문제이다.

일단 대부분의 iframe 주소는 정적으로 사용되게 되는데

< iframe src="{{주소}}" > </ifame>

이 주소가 API 형식으로 특정 데이터를 받아와서 삽입 되었을때 문제가 발생하였다.

대략적인 흐름은 다음과 같다.

  1. 부모창 Loading
  2. 부모창 api 호출
  3. api 결과값에 있는 주소로 iframe 의 src 변경 ( $(“iframe”).attr(“src”, “주소”); )
  4. iframe도 로딩

이러한 흐름을 갖고 있는 화면을 만들었는데. 이상하게 간헐적으로..
해당 페이지에서 뒤로가기 버튼을 눌렀을때. 부모창의 이전 페이지로 가야 하는데 iframe 의 창이 부모창의 모습이 나와있는 형태로 보이는 이슈가 발생했다. 즉 아래 화면처럼 ..


사실 저 이슈는 개발 PC에서는 거의 발생하지 않았고 성능이 느린 윈도우 PC 에서 주로 발생하여서, 개인적으로는 브라우저 버그 또는 특정 플랫폼 버그( 윈도우…) 라고 생각하고 해결할 생각이 없었다.

하지만 시간이 남아 처음부터 다시 생각했고 문제의 원인을 찾았다.

문제는 # 이라는 값 때문이였는데. iframe 의 src 값은 비어있기 때문에 초기 값은 “” 즉 null 값이 들어갈수 밖에 없었고. 이게 웹 유효성 검사에서. 지적당해서 해당 값에 의미없는  값인 “#” 이 들어가게 되었다.  이게 api를 통해 iframe 주소 값을 받아오게 되면

$( "iframe" ).attr( "src", "" );

란 javascript로 변경 되었는데. 이게 타이밍 이슈가 있는 로직이였다.

설명을 다시 하자면.  # 은 자기자신 즉 현재 부모창을 가르키는 역할을 하는데 iframe 에 값이 없는것이 아니라. 현재 부모창을 다시 한번 로드하는 형태이다.

대부분의 api 는 빠르게 요청되어서.
1. api로 주소 받아온다음
2. iframe 다시 로드
되는데. 일부 느린 PC에서는 1번 부분보다 자식창의 현재 # 값의 로딩이 더 빠른경우가 발생했다.

그 이후에 2번이 로딩 되니 당연히 iframe의 주소 히스토리는
1)# , 2)새롭게 로드된 화면  순서일수 밖에 없으며 뒤로가기를 누르고나 history.back(), history.go(-1)을 하게 되면 1) 번 #으로 돌아갈수밖에 없다. ( 그래서 위에 화면처럼 나온다. )

이제 문제를 확인했으니. 해당 이슈를 회피하거나. 근본적인 이슈를 제거 해야 한다.
HTML에 src에 값이 들어가있지 않으면.. 특정 QA를 통과할수가 없으므로. #은 무조건 사용해야 하는 상황이기 때문에 javascript로 처리해야 하는데…

그래서 아래 코드를 바꿔 보기로  했다.

$("iframe").attr("src","새로운주소");

아예 iframe  자식 화면의 브라우저 히스토리를 갱신해버리면 # 값으로 뒤로 갈 이유가 없을것이라고 판단 위 코드를  다음과 같이 변경 했는데 결과적으로 문제가 해결되었다.

$("iframe").get(0).contentWindow.location.replace("새로운주소");

위 코드는 iframe 의 히스토리를 날려버리기때문에 뒤로가기했을때 전혀 문제가 발생하지 않는다.

별거 아닌 코드인것 같지만. 생각보다 이슈 찾고 고민하느냐고 삽질을 많이했다. 특히 위 이슈는 재현이 안되므로..

정리하면.

1. 동적으로 iframe 주소가 로딩되는경우
2. $().attr() 방식보다는
3. DOM기본 함수의 location.replace를 사용하자.

 

1 댓글

  1. 좋은 내용 감사히 잘 읽었습니다. 크롬을 사용했을 때, img 태그의 src에 #이 들어가있는 경우 해당 페이지가 2번씩 로드되는 문제를 겪은 적이 있는데 단순한 버그인줄 알았더니 그게 아니었나봅니다.

초심자 에 응답 남기기 응답 취소

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.

다음의 HTML 태그와 속성을 사용할 수 있습니다: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>