[javascript] 웹 페이지가 iframe 내부 또는 브라우저 창에 직접로드되는지 식별하는 방법은 무엇입니까?

iframe 기반 페이스 북 앱을 작성 중입니다. 이제 동일한 HTML 페이지를 사용하여 일반 웹 사이트와 페이스 북의 캔버스 페이지를 렌더링하려고합니다. 페이지가 iframe에로드되었는지 브라우저에 직접로드되었는지 확인할 수 있는지 알고 싶습니다.



답변

브라우저는 동일한 출처 정책window.top 으로 인해 액세스를 차단할 수 있습니다 . IE 버그도 발생합니다. 작동 코드는 다음과 같습니다.

function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

topself둘 다 window객체 parent이므로 창이 맨 위 창인지 확인합니다.


답변

부모와 같은 원점에서 iframe에있을 때, window.frameElement메소드는 윈도우가 포함 된 요소 (예 : iframe또는 object)를 반환합니다 . 그렇지 않으면 최상위 컨텍스트에서 탐색하거나 상위 프레임과 하위 프레임의 출처가 서로 다른 경우로 평가됩니다 null.

window.frameElement
  ? 'embedded in iframe or object'
  : 'not embedded or cross-origin'

모든 최신 브라우저에서 기본적으로 지원 되는 HTML 표준 입니다.


답변

RoBorg는 정확하지만 보조 메모를 추가하고 싶었습니다.

IE7 / IE8에서 Microsoft가 브라우저에 탭을 추가했을 때 조심하지 않으면 JS에 혼란을 야기하는 한 가지 문제가 발생했습니다.

이 페이지 레이아웃을 상상해보십시오.

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")

이제 “baz”프레임에서 링크를 클릭하십시오 ( “baz”프레임에로드 된 대상 없음).

로드 된 페이지를 special.html로 호출하고 JS를 사용하여 “it”에 “bar”라는 상위 프레임이 있는지 확인하면 true (예상)를 반환합니다.

이제 special.html 페이지가로드 될 때 부모 프레임을 검사하고 (존재 여부와 이름이 “바”인 경우) 바 프레임에 다시로드된다고 가정합니다.

if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}

여태까지는 그런대로 잘됐다. 이제 버그가 온다.

일반 링크처럼 원래 링크를 클릭하고 “baz”프레임에 special.html 페이지를로드하는 대신 마우스 가운데 버튼을 클릭하거나 새 탭에서 열도록 선택했습니다.

새 탭이로드되면 ( 부모 프레임이 전혀 없습니다! ) IE는 끝없는 페이지 로딩 루프에 들어갑니다! IE가 JavaScript의 프레임 구조를 “복사”하여 새 탭에 부모가 있고 해당 부모에 “bar”라는 이름이 있기 때문입니다.

좋은 소식은 확인하는 것입니다.

if(self == top){
  //this returns true!
}

새 탭에서 true를 반환하므로이 이상한 조건을 테스트 할 수 있습니다.


답변

Firefox 6.0 Extension (Addon-SDK 1.0)의 컨텐츠 스크립트에서 허용 된 답변이 작동하지 않았습니다. Firefox는 각각의 최상위 레벨 창과 모든 iframe에서 컨텐츠 스크립트를 실행합니다.

콘텐츠 스크립트 내에서 다음과 같은 결과를 얻습니다.

 (window !== window.top) : false
 (window.self !== window.top) : true

이 출력에 대한 이상한 점은 코드가 iframe에서 실행되는지 아니면 최상위 창에서 실행되는지에 관계없이 항상 동일하다는 것입니다.

반면에 Chrome은 최상위 창 내에서 한 번만 내 콘텐츠 스크립트를 실행하는 것처럼 보이므로 위의 작업은 전혀 작동하지 않습니다.

두 브라우저의 콘텐츠 스크립트에서 마침내 나를 위해 일한 것은 다음과 같습니다.

 console.log(window.frames.length + ':' + parent.frames.length);

iframe이 없으면 인쇄 0:0되며, 하나의 프레임이 포함 된 최상위 창 1:1에서 인쇄 되며, 문서의 유일한 iframe에서 인쇄 0:1됩니다.

이렇게하면 내 확장 프로그램에 iframe이 있으면 두 브라우저에서, iframe 중 하나에서 실행되는 경우 Firefox에서 추가로 결정할 수 있습니다.


답변

이 예제가 이전 웹 브라우저에서 어떻게 작동하는지 잘 모르겠지만 IE, Firefox 및 Chrome에서 문제없이 사용합니다.

var iFrameDetection = (window === window.parent) ? false : true;


답변

나는 이것을 사용하고있다 :

var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);


답변

이를 수행하는 방법에 대한 예제로이 JavaScript 함수를 사용하십시오.

function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe 
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe 
// and the domains are different.
var myresult = true;
try {
    var tophref = top.location.href;
    var tophostname = top.location.hostname.toString();
    var myhref = location.href;
    if (tophref === myhref) {
        myresult = true;
    } else if (tophostname !== "www.yourdomain.com") {
        myresult = false;
    }
} catch (error) {
  // error is a permission error that top.location.href is not accessible 
  // (which means parent domain <> iframe domain)!
    myresult = false;
}
return myresult;
}