다른 도메인에서 iframe의 크기를 조정하는 방법
-편집하다
몇 가지 해결책을 보려면 아래로 스크롤하십시오. 또는이 작업을 수행하지 않는 방법을 읽으십시오. D
여러 시간의 코드 해킹 후 결론은 내 도메인에서 렌더링되는 스크롤바를 포함하여 iframe 내부의 모든 항목에 액세스 할 수 없다는 것입니다. 나는 아무 소용이없는 많은 기술을 시도했다.
시간을 절약하려면이 경로를 따르지 말고 도메인 간 통신에 sendMessages를 사용하십시오. 내가 사용하는 HTML <5 용 플러그인이 있습니다. 좋은 예를 보려면 맨 아래로 이동하십시오.
지난 며칠 동안 iframe을 사이트에 통합하려고했습니다. 이것은 다른 쪽이 개발하고 API를 개발하는 동안 단기 솔루션입니다 (몇 달이 걸릴 수 있습니다 ...). 그리고 이것이 우리가 한 단기 솔루션이기 때문에 easyXDM을 사용하고 싶습니다. 다른 도메인에 액세스 할 수 있지만 요청하기가 충분히 어렵습니다. p3p 헤더를 그대로 추가합니다 .....
iframe 3 개
내가 찾은 가장 가까운 해결책은 3 개의 iframe 이었지만 크롬과 사파리를 생각하기 때문에 사용할 수 없습니다.
크롬에서 열기
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
스크롤바 측정
스크롤 높이를 사용하여 양식 크기를 조정하는 방법에 대한 또 다른 게시물을 찾았습니다. 이론적으로는 잘 작동하지만 iframe 스크롤 높이를 사용하여 제대로 적용 할 수 없었습니다 ..
document.body.scrollHeight
그것은 obvoisly body height를 사용합니다 (이 속성에 100 % 액세스 할 수 없음은 x-domains 문서 높이가 아니라 클라이언트 디스플레이 canvaz를 기반으로 함)
iframe 높이를 얻기 위해 jquery를 사용해 보았습니다.
$('#frameId').Height()
$('#frameId').clientHeight
$('#frameId').scrollHeight
크롬과 ie에서 다른 값을 반환하거나 전혀 의미가 없습니다. 문제는 프레임 내부의 모든 것이 거부된다는 것입니다. 스크롤바도 마찬가지입니다.
계산 된 스타일
그러나 iframe의 크롬에서 요소를 검사하고 요소를 검사하면 iframe 내부의 문서 크기가 표시됩니다 (jquery x-domain을 사용하여 iframe.heigh-액세스 거부 됨) 계산 된 CSS에는 아무것도 없습니다.
이제 크롬은 그것을 어떻게 계산합니까? (편집-브라우저는 이러한 모든 설정을 계산하기 위해 렌더링 엔진의 빌드를 사용하여 페이지를 다시 렌더링합니다. 그러나 도메인 간 사기를 방지하기 위해 어디에도 첨부되지 않습니다. 그래서 ..)
HTML4
HTML4.x의 사양을 읽었으며 document.element를 통해 노출 된 읽기 전용 값이 있어야하지만 jquery를 통해 액세스가 거부되었다고 말합니다.
프록시 프레임
나는 사용자가 iframe을 통해 로그인하고 프록시가 실제 콘텐츠 대신 로그인 페이지를 얻을 때까지 사이트를 다시 프록시하고 계산하는 경로를 따라갔습니다. 또한 일부 페이지를 두 번 호출하는 것은 허용되지 않습니다.
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
페이지 다시 렌더링
여기까지 가지 않았지만 소스를보고 소스 파일을 기반으로 페이지를 다시 렌더링하는 jscript 엔진이 있습니다. 그러나 그것은 그 jscripts를 해킹해야 할 것입니다. 그리고 그것은 상업적인 엔티티에 이상적인 상황이 아닙니다 ... 그리고 일부는 순수한 자바 애플릿이나 서버 측 렌더링을 불러옵니다.
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java가 아닌 jscript
2013 년 9 월 업데이트 수정
이 모든 것은 HTML5 소켓으로 할 수 있습니다. 그러나 easyXDM은 HTML5가 아닌 불만 페이지에 대한 훌륭한 대안입니다.
솔루션 1 매우 훌륭한 솔루션!
easyXDM 사용
서버에서 다음과 같은 형식으로 페이지를 설정합니다.
<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
var transport = new easyXDM.Socket(/** The configuration */{
remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",
//ID of the element to attach the inline frame to
container: "embedded",
onMessage: function (message, origin) {
var settings = message.split(",");
//Use jquery on a masterpage.
//$('iframe').height(settings[0]);
//$('iframe').width(settings[1]);
//The normal solution without jquery if not using any complex pages (default)
this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
}
});
</script>
</head>
<body>
<div id="embedded"></div>
</body>
호출자 도메인에서는 intermiedate_frame html과 easyXDM.js를 같은 위치에 추가하기 만하면됩니다. 상위 폴더처럼-상대 디렉토리 또는 포함 된 폴더에 액세스 할 수 있습니다.
옵션 1
모든 페이지에 스크립트를 추가하지 않으려면 옵션 2를보십시오!
그런 다음 크기 조정이 필요한 각 페이지 끝에 간단한 jscript를 추가 할 수 있습니다. 각 페이지에 easyxdm을 포함 할 필요가 없습니다.
<script type="text/javascript">
window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); };
</script>
전송하는 매개 변수를 수정했습니다. 너비가 제대로 작동하도록하려면 다른 도메인의 페이지에 다음과 유사한 스타일의 페이지 너비를 포함해야합니다.
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
background-color: rgb(75,0,85);
color:white;
width:660px
}
a {
color:white;
visited:white;
}
</style>
이것은 나를 위해 잘 작동합니다. 너비가 포함되지 않은 경우 프레임은 약간 이상하게 작동하고 어떤 것이되어야하는지 추측하려고 시도합니다. 필요한 경우 축소되지 않습니다.
옵션 2
변경 사항을 폴링하도록 중간 프레임 수정
중간 프레임은 다음과 같아야합니다 ..
<!doctype html>
<html>
<head>
<title>Frame</title>
<script type="text/javascript" src="easyXDM.js">
</script>
<script type="text/javascript">
var iframe;
var socket = new easyXDM.Socket({
//This is a fallback- not needed in many cases
swf: "easyxdm.swf",
onReady: function(){
iframe = document.createElement("iframe");
iframe.frameBorder = 0;
document.body.appendChild(iframe);
iframe.src = "THE HOST FRAME";
iframe.onchange = messageBack();
},
onMessage: function(url, origin){
iframe.src = url;
}
});
//Probe child.frame for dimensions.
function messageBack(){
socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth);
};
//Poll for changes on children every 500ms.
setInterval("messageBack()",500);
</script>
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
iframe {
width: 100%;
height: 100%;
border: 0px;
}
</style>
</head>
<body>
</body>
</html>
간격은 크기가 변경되면 chaeck하는 데 더 효율적으로 만들 수 있으며 치수 변경이 500ms마다 메시지를 게시하지 않는 경우에만 보낼 수 있습니다. 이 검사를 구현하면 폴링을 50ms까지 변경할 수 있습니다! 재미있게
여러 브라우저에서 작업하고 빠릅니다. 훌륭한 디버깅 기능 !!
Excellent Work to Sean Kinsey who made the script!!!
솔루션 2 (작동하지만 좋지 않음)
따라서 기본적으로 다른 도메인과 상호 합의한 경우 sendmessage를 처리 할 라이브러리를 추가 할 수 있습니다. 다른 도메인에 대한 액세스 권한이없는 경우 .. 계속해서 더 많은 해킹을 찾으십시오. 내가 찾은 이들을 찾거나 완전히 정당화 할 수 없기 때문입니다.
따라서 다른 도메인은 여기에 헤드 태그를 포함합니다.
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>
club.js에는 크기 조정 호출을 위해 만든 일부 사용자 정의 호출이 있습니다.
$(document).ready(function () {
var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$('a[href]').each(function(){
this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
});
그리고 귀하의 페이지는 모든 노력을 다하고 멋진 스크립트를 가지고 있습니다 ...
//This is almost like request.querystring used to get the iframe data
function querySt(param, e) {
gy = e.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy[i].split("=");
if (ft[0] == param) {
return ft[1];
}
}
}
$(function () {
// Keep track of the iframe dimensions.
var if_height;
var if_width;
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
// passed via query string or hard coded into the child page, it depends on your needs).
src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href),
// Append the Iframe into the DOM.
iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe');
// Setup a callback to handle the dispatched MessageEvent event. In cases where
// window.postMessage is supported, the passed event will have .data, .origin and
// .source properties. Otherwise, this will only have the .data property.
$.receiveMessage(function (e) {
// Get the height from the passsed data.
//var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1'));
var h = querySt("if_height", e.data);
var w = querySt("if_width", e.data);
if (!isNaN(h) && h > 0 && h !== if_height) {
// Height has changed, update the iframe.
iframe.height(if_height = h);
}
if (!isNaN(w) && w > 0 && w !== if_width) {
// Height has changed, update the iframe.
iframe.width(if_width = w);
}
//For debugging only really- can remove the next line if you want
$('body').prepend("Recieved" + h + "hX" + w + "w .. ");
// An optional origin URL (Ignored where window.postMessage is unsupported).
//Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks!
}, 'http://www.OTHERDOMAIN.co.uk');
});
옵션 3
이제는 도메인 간 iFrame 크기 조정을 관리하기위한 작은 JS 라이브러리이며, 여전히 iFrame에 약간의 JavaScript가 있어야하지만 종속성이없는 기본 JS의 2.8k (765 바이트 Gzip)에 불과합니다. 부모 페이지가 호출 할 때까지 아무것도하지 않습니다. 이것은 다른 사람 시스템의 좋은 게스트임을 의미합니다.
이 코드는 mutationObserver를 사용하여 DOM 변경을 감지하고 크기 조정 이벤트를 찾아 iFrame이 콘텐츠에 맞게 크기를 유지하도록합니다. IE8 +에서 작동합니다.