it-swarm-ko.com

iframe 내부 또는 브라우저 창에서 직접로드 확인 방법

나는 iframe 기반의 페이스 북 앱을 쓰고있다. 이제 페이스 북에서 캔버스 페이지뿐만 아니라 일반 웹 사이트를 렌더링하는 데 동일한 html 페이지를 사용하고 싶습니다. 페이지가 iframe 내부에로드되었는지 직접 브라우저에로드되었는지 확인할 수 있는지 알고 싶습니다.

518
akshat

브라우저는 동일한 원본 정책 으로 인해 window.top에 대한 액세스를 차단할 수 있습니다. IE 버그도 발생합니다. 다음은 작업 코드입니다.

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

topself은 둘 다 window 개체이며 (parent과 함께), 창을 맨 위 창으로 볼 수 있습니다.

978
Greg

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

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

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

78

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 페이지가로드되면 부모 프레임을 확인하고 (존재 여부 및 이름), "bar"이면 막대 프레임에 다시로드됩니다.

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

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

보통 링크와 같은 원래 링크를 클릭하고 "baz"프레임에 special.html 페이지를로드하는 대신 중간 클릭하거나 새 탭에서 열려고합니다

새 탭이 상위 프레임이없는 로드 될 때! ) IE는 끝없는 페이지 로딩 루프를 시작합니다 새로운 탭에는 부모가 있고 그 부모는 "바"라는 이름을 갖기 위해 IE가 JavaScript의 프레임 구조를 "복사"하기 때문에! !.

좋은 소식은 다음과 같습니다.

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

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

25
scunliffe

대답은 Firefox 6.0 Extension (Addon-SDK 1.0)의 콘텐츠 스크립트 내에서 작동하지 않았습니다. Firefox는 최상위 창과 모든 iframe에서 콘텐츠 스크립트를 각각 실행합니다.

내용 스크립트에서 다음 결과를 얻습니다.

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

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

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

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

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

Iframe을 사용하지 않으면 0:0가 인쇄되고 한 프레임이 포함 된 최상위 창에 1:1가 인쇄되고 문서의 유일한 iframe에는 0:1가 인쇄됩니다.

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

18
magnoz

이전 웹 브라우저에서이 예제가 어떻게 작동하는지 모르겠지만 Internet Explorer, Firefox 및 Chrome에서는이 코드를 사용하지 않고 다음과 같이 사용합니다.

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

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

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

이를 수행하는 방법에 대한 예제로이 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;
}
2
Rolf

사실 window.parent를 확인하는 데 익숙해졌습니다.하지만 최근에 창은 순환 객체이며 항상 부모 키, iframe 또는 iframe이 없습니다.

의견은 window.parent와 비교하여 열심히 제안합니다. iframe이 parent와 완전히 동일한 웹 페이지 인 경우 이것이 작동하는지 잘 모르겠습니다.

window === window.parent;
1
Jabran Saeed

최고의 브라우저 프레임 깨는 스크립트

다른 해결책은 나를 위해 일하지 않았다. 이것은 모든 브라우저에서 작동합니다.

클릭 재킹 (clickjacking)을 방어하는 한 가지 방법은 액자 화되지 않아야하는 각 페이지에 "프레임 브레이커 (frame-breaker)"스크립트를 포함시키는 것입니다. 다음 방법을 사용하면 X-Frame-Options-Header를 지원하지 않는 레거시 브라우저에서도 웹 페이지가 프레임되지 않습니다.

문서 HEAD 요소에 다음을 추가하십시오.

<style id="antiClickjack">body{display:none !important;}</style>

먼저 스타일 요소 자체에 ID를 적용합니다.

<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

이렇게하면 모든 것이 문서 HEAD에있을 수 있으며 API에 하나의 메소드/taglib 만 있으면됩니다.

참조 : https://www.codemagi.com/blog/post/194

1
Albert Olivé

페이스 북 앱의 맥락에서 묻기 때문에 초기 요청이있을 때 서버에서이를 감지하는 것이 좋습니다. 페이스 북은 fb_sig_user 키가 iframe에서 호출되면 querystring 데이터를 따라 전달합니다.

어쨌든 앱에서이 데이터를 확인하고 사용해야 할 수도 있으므로이를 사용하여 렌더링 할 적절한 컨텍스트를 결정하십시오.

1
HectorMac

이것은 나를 위해 가장 간단한 해결책이되었습니다.

    <p id="demofsdfsdfs"></p>

<script>

if(window.self !== window.top) {

//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";

}else{

//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}

</script>
0
Alex Roseland