답변:
브라우저는 동일한 출처 정책window.top
으로 인해 액세스를 차단할 수 있습니다 . IE 버그도 발생합니다. 작동 코드는 다음과 같습니다.
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
top
와 self
둘 다 window
객체 parent
이므로 창이 맨 위 창인지 확인합니다.
window.self !== window.top
반환 true
됩니다 . frame
iframe
부모와 같은 원점에서 iframe에있을 때, window.frameElement
메소드는 윈도우가 포함 된 요소 (예 : iframe
또는 object
)를 반환합니다 . 그렇지 않으면 최상위 컨텍스트에서 탐색하거나 상위 프레임과 하위 프레임의 출처가 서로 다른 경우로 평가됩니다 null
.
window.frameElement
? 'embedded in iframe or object'
: 'not embedded or cross-origin'
모든 최신 브라우저에서 기본적으로 지원 되는 HTML 표준 입니다.
null
의 내부와 외부iframe
Returns the element (such as <iframe> or <object>) in which the window is embedded, or null if the element is either top-level or is embedded into a document with a different script origin; that is, in cross-origin situations.
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를 반환하므로이 이상한 조건을 테스트 할 수 있습니다.
window.parent
.
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에서 추가로 결정할 수 있습니다.
document.defaultView.self === document.defaultView.top
또는을 시도하십시오 window !== window.top
. Firefox의 애드온 SDK의 컨텐츠 스크립트에서 글로벌 self
오브젝트는 기본 스크립트와 통신하는 데 사용되는 오브젝트입니다.
이 예제가 이전 웹 브라우저에서 어떻게 작동하는지 잘 모르겠지만 IE, Firefox 및 Chrome에서 문제없이 사용합니다.
var iFrameDetection = (window === window.parent) ? false : true;
!(window===window.parent)
나는 이것을 사용하고있다 :
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
.indexOf("HTMLIFrameElement")
?
이를 수행하는 방법에 대한 예제로이 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;
}
다른 솔루션은 저에게 효과적이지 않았습니다. 이것은 모든 브라우저에서 작동합니다.
클릭 재킹을 방지하는 한 가지 방법은 각 페이지에 프레임 화해서는 안되는 "프레임 차단기"스크립트를 포함시키는 것입니다. 다음 방법은 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가 하나만 필요합니다.
나는 실제로 window.parent를 확인하는 데 사용했고 그것은 나를 위해 일했지만 최근에는 창은 순환 객체이며 항상 부모 키, iframe 또는 iframe이 없습니다.
의견에 따르면 window.parent와 비교하는 것이 좋습니다. iframe이 부모와 동일한 웹 페이지 인 경우 이것이 작동하는지 확실하지 않습니다.
window === window.parent;
window.parent === window
사실입니다. 그래서 당신의 대답은 틀립니다. 그리고이 비교는 검사에 사용될 수 있습니다 (적어도 크롬에서는 다른 브라우저에서 테스트하지 않았습니다).
몇 번 사용했던 고대 코드입니다.
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
(parent.location == self.location)
parent.location
. 그렇지 않으면 예외가 발생합니다
사용자가 페이스 북 페이지 탭 또는 캔버스에서 앱에 액세스하고 있는지 확인하려면 서명 된 요청을 확인하십시오. 얻지 못하면 아마도 사용자가 페이스 북에서 액세스하지 않는 것입니다. signed_request 필드 구조 및 필드 내용을 확인하십시오.
php-sdk를 사용하면 다음과 같이 서명 된 요청을 얻을 수 있습니다.
$signed_request = $facebook->getSignedRequest();
서명 된 요청에 대한 자세한 내용은 여기를 참조하십시오.
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
그리고 여기:
https://developers.facebook.com/docs/reference/login/signed-request/
이것은 나를 위해 가장 간단한 해결책이되었습니다.
<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>
이 자바 스크립트를 각 페이지에 작성하십시오
if (self == top)
{ window.location = "Home.aspx"; }
그런 다음 자동으로 홈페이지로 리디렉션됩니다.