iframe 을 사용해볼 일이 생겨, 이참에 잘 모르고 있던 iframe 을 정리해보고자 한다.

https://en.wikipedia.org/wiki/HTML_element#Frames

iframe 은 Frame 의 일종이다.

Frame 은 브라우저 창을 여러 세그먼트로 분할해 서로 다른 여러 페이지들을 한 페이지에서 표현할 수 있다.

하지만 Frame 은 여러 이유로 W3C 에서 사용하지 않게 권고 하면서, Frame 구조로 된 웹 사이트는 점점 줄어드는 추세로 돌아섰고, HTML5 규격에서는 제외 되었다.

하지만 아직 Frame 구조로 된 웹 사이트들이 남아있기 때문에 호환성을 위해 일부 브라우저에는 여전히 지원하고 있다.

iframe 은 inline frame 의 줄임말이며, 페이지에 Frame 을 넣을 때 사용한다.

Frame 와는 달리, iframe 태그는 HTML5 에서도 계속 지원된다.

여러 기 에서 다른 웹사이트에 Banner 혹은 여러 형태의 Plugin 을 제공하기 위해서 많이 사용 되고 있다.
(Facebook, Google Ads, Youtube 등등)

간단 예제

Iframe 은 여러 attribute 를 가지고 있다.

  • name: iframe 이름
  • src: 페이지 경로
  • srcdoc: html 을 직접 넣을 수 있다. 만약 브라우저가 srcdoc 속성을 지원하지 않으면, src 로 대체된다.
    ex) srcdoc="<b>test</b>"
  • width/height : 프레임 크기
  • allow : fullscreen | payment API 등에 대한 액세스 허용 여부
    ex) allow="fullscreen" allow="payment"
  • referrerpolicy : iframe을 가져올 때 보낼 리퍼러 정보를 지정
    - origin | origin-when-cross-origin | same-origin | strict-origin | strict-origin-when-cross-origin
  • sandbox: 보안을 위해 iframe 에서 form 이나 자바스크립트 등이 실행이 되지 못하게 할 수 있다.
    - 비어 있다면: 모든 제한 사항을 적용한다.
    - allow-forms: Form 허용
    - allow-modals: modal window 를 열 수 있도록 허용
    ex) alert()
    - allow-same-origin: 도메인이 다르더라도, CORS 를 통과된 것처럼 허용
    - allow-scripts: 스크립트를 실행할 수 있도록 허용
    - allow-popups: window.open 등의 팝업 허용
    - allow-storage-access-by-user-activation: Storage API 허용

Iframe 와 Browsing Context

하나의 문서에는 하나의 window 를 가지게된다. 그렇다면, 서로 다른 iframe 에서 window 는 어떻게 구분될까?

Browsing Context 는 브라우저가 표시하는 환경이다.

브라우저의 각각의 Browsing Context 에는 고유 한 Session History 와 Document 를 가진다.

iframe 도 독립적인 Browsing Context 를 가진다.

각각 Browsing Context 는 연관된 WindowProxy 객체가 있다.

WindowProxy 는 Window 를 가르키는 객체다.

  • window.top: 최상위 브라우징 컨텍스트
  • window.parent: 부모 브라우징 컨텍스트
  • window.frameElement: 부모 브라우징 컨텍스트 Elements 를 반환한다.

iframe 에 로드된 페이지는 부모 페이지와 별개의 페이지다. 때문에 부모 window context 와는 별개의 window context 를 가진다.

하나의 페이지에서는 여러 iframe 을 포함 할 수 있다. 전체 iframe 목록을 확인하기위해서 document.getElementsByTagName('iframe') 혹은 window.frames 으로 확인이 가능하다.

이때 window.frames 은 ArrayLike 인 frameList 를 반환한다.

각각의 부모 페이지에서 iframe 의 window 에 접근하기 위해서는 contentWindow 로 접근할 수 있다.

contentWindow 속성은 HTMLIFrameElement 의 Window 개체를 반환 하게 되며, 이 개체를 사용하여 iframe의 문서 및 내부 DOM에 액세스 및 조작할 수 있다.

document.getElementsByTagName('iframe')[0].contentWindow

window.frames[0].contentWindow

만약 iframe 에서 부모 window 에 접근해야 한다면 어떻게 해야할까?

각각의 iframe 의 window 는 window 로 접근이 가능하며, 부모 window 에 접근하기 위해서는 window.parent 로 접근이 가능하다.

이때 주의할점은 script 를 사용하기 때문에, sandbox 를 세팅했다면, “allow-scripts allow-same-origin” 설정이 필요하다.

iframe 의 load 가 끝난 이후 부모페이지의 load 가 끝나는것을 확인할 수 있다.

Iframe 과 Dom

브라우저에서 HTML 을 전달받으면, DOM 을 Parsing 하고, Render Tree 를 만들게 되고, RenderLayer Tree 로 화면을 표현하게 된다.

이때, Iframe 을 만나게 되면 어떻게 될까?

DOM Parsing 중 iframe 을 만나도 DOM Parsing 을 중단 시키지 않는다. Node 에 Iframe 을 추가하고, 새로운 Render Layer 를 만들게 된다.

부모 문서의 load 가 완료되고, iframe 에서 요청한 문서가 Load 되면, DOM parsing 및 Rendering 이 시작된다. 이때 script 가 실행되면, 같은 event loop 에서 동작하기 때문에 부모에서 실행되던 스크립트가 밀릴 수 있다.

https://www.chromium.org/developers/design-documents/oop-iframes/oop-iframes-rendering#TOC-Out-of-process-iframes

마치며

iframe 과 window.open 는 새로운 window 의 Browsing Context 를 생성한다.

생성된 Browsing Context 는 독립적으로 보안을 보장 받지만, 상황에 따라서 데이터 전달 이 필요할 수 있다.

다음글로 각각의 Browsing Context 간에 데이터를 전달하는 방법을 정리해보고자 한다.

Javascript is great We may not be great

Javascript is great We may not be great