iframe между доменами размер



как изменить размер iframe из другого домена



- Edit



прокрутите вниз для некоторых решений.. или читайте о том, как этого не делать :D



после многих часов взлома кода-вывод заключается в том, что ничего внутри iframe не доступно, даже полосы прокрутки, которые отображаются на моем домене. Я пробовал много методов безрезультатно.



чтобы сэкономить ваше время, даже не спускайтесь по этому маршруту, просто используйте sendMessages для междоменной связи.
Есть плагины для HTML




последние несколько дней я пытался интегрировать iframe в сайт. Это краткосрочное решение, в то время как другая сторона разрабатывает и API(может занять несколько месяцев...)
И потому что это как краткосрочное решение, мы хотим использовать easyXDM - у меня есть доступ к другому домену, но его достаточно сложно попросить их добавить заголовок p3p так оно и есть.....



3 iframes



самое близкое решение, которое я нашел, было 3 iframes - но оно идет в голове chrome и safari, поэтому я не могу его использовать.



открыть в chrome



http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179



измерьте полосы прокрутки



я нашел еще один пост о том, как использовать scrollheight попытаться размер формы.. теоретически это работает хорошо, но я не мог правильно применить его, используя высоту прокрутки iframes..



document.body.scrollHeight


что очевидно использует высоту тела (не может получить доступ к этим свойствам 100% основан на клиентах отображения canvaz а не x-domains высота документа)



я попытался использовать jquery, чтобы получить высоту iframes



$('#frameId').Height()

$('#frameId').clientHeight

$('#frameId').scrollHeight


возвращаемые значения отличаются в chrome и ie-или просто не имеют смысла вообще.
Проблема в том, что все внутри кадра отказано-даже полоса прокрутки...



Вычисляемые Стили



но если я Проинспектировать элемент в браузере Chrome кадра этого проклятого показывает мне размеры документов внутри iframe (с помощью jQuery х-домен, чтобы получить элемент iframe.Хей - доступ запрещен)
Там нет ничего в вычисленном CSS enter image description here



теперь, как chrome вычисляет это? (edit-браузер повторно отображает страницу, используя ее сборку в движке рендеринга, чтобы вычислить все это настройки-но не прикреплены нигде, чтобы предотвратить междоменное мошенничество.. так..)



HTML4



Я читал спецификацию HTML4.x и там говорится, что должны быть доступны только для чтения значения через документ.элемент, но это доступ запрещен через 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.. и это не идеальная ситуация для хозяйствующих субъектов...
и некоторые invole чистые Java-апплеты или рендеринг на стороне сервера



http://en.wikipedia.org/wiki/Server-side_JavaScript



http://htmlunit.sourceforge.net/


http://maxq.tigris.org/





изменить 09-2013
обновление



все это можно сделать с помощью сокетов 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>


это отлично работает для меня. Если ширина не включена, то рамка ведет себя немного странно и kind'of пытается угадать, что это должно быть .. и не будет сжиматься, если вам это нужно.



вариант 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, если размер имеет изменение и только отправить, если изменения размеров isntead размещения сообщений каждые 500 мс. если вы реализуете эту проверку, то вы можете изменить опрос всего за 50 мс! получайте удовольствие





работа через браузеры и быстро. Отличные возможности отладки !!



Excellent Work to  Sean Kinsey  who made the script!!!




решение 2 (работает, но не большой)



так в принципе, если у вас есть взаимное соглашение с другим доменом, то вы можете добавить библиотеку для обработки sendmessage. Если у вас нет доступа к другому домену.. Продолжайте искать больше хаков-потому что я не мог найти или полностью оправдать их, которые я нашел.



таким образом, другой домен будет включать в себя эти там Head tag



<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>


в клубе.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+)(?:&|$)/, ''));
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



их теперь небольшая библиотека JS для управления изменением размера междоменных iFrames, она по-прежнему требует, чтобы iFrame имел немного JavaScript в нем, однако это всего лишь 2.8 k (765 байт Gzipped) собственного JS, который не имеет никаких зависимостей, и он ничего не делает, пока не будет вызван родительской страницей. Это означает, что это хороший гость на других системах людей.



этот код использует mutationObserver для обнаружения изменений DOM, а также ищет события изменения размера, так что iFrame остается размером с содержимым. Работает в IE8+.



https://github.com/davidjbradshaw/iframe-resizer

853   9  

9 ответов:

дело в том, что нет другого способа, кроме использования междоменных сообщений для этого, так как вам нужно получить вычисленную высоту из документа в одном домене, в документ в другом домене.

Так что, либо вы делаете это с помощью postMessage (работает во всех браузерах moder), или вы тратите 5 минут на адаптацию изменить размер iframe пример от easyXDM.

другой стороне действительно просто нужно скопировать несколько файлов в свой домен и добавить одну строку кода свой документ..

подобно тому, что упоминал Шон, вы можете использовать postMessage. Я потратил так много времени, пытаясь по-разному изменить размер iframe с кросс-доменом, но не повезло, пока я не наткнулся на эту замечательную запись в блоге Дэвида Уолша:http://davidwalsh.name/window-iframe

это комбинация моего кода и решения Дэвида. Мое решение направлено специально на изменение размера iframes.

на дочерней странице найдите высоту страницы и передайте ее родителю страница (которая содержит iframe). Замените element_id своим идентификатором элемента (html, body, whatever).

<script>
function adjust_iframe_height(){
    var actual_height = document.getElementById('element_id).scrollHeight;
    parent.postMessage(actual_height,"*"); 
    //* allows this to post to any parent iframe regardless of domain
}
</script>

<body onload="adjust_iframe_height();"> 
//call the function above after the content of the child loads

в Родительском окне добавьте этот код. Замените iframe_id своим идентификатором iframe:

<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child window
eventer(messageEvent,function(e) {
  console.log('parent received message!:  ',e.data);
  document.getElementById('iframe_id').height = e.data + 'px';
},false);
</script>

Если вы откроете консоль, вы увидите, что высота печатается в журнале консоли. Это поможет вам в отладке, поэтому я оставил его там.

лучшие, Бейкер

посмотрев много разных решений для этого, я написал простую небольшую библиотеку, чтобы учесть ряд различных вариантов использования. Поскольку мне нужно было решение, которое поддерживало несколько пользовательских iFrames на странице портала, поддерживаемый браузер изменяет размер и может справиться с загрузкой JavaScript страницы хоста после iFrame. Я также добавляю поддержку размеров по ширине и функцию обратного вызова и разрешаю переопределение тела.маржа, как вы, вероятно, захотите, чтобы этот набор был нуль.

https://github.com/davidjbradshaw/iframe-resizer

код iframe-это просто немного автономный JavaScript, так что это хороший гость на страницах других людей.

затем скрипт инициализируется на главной странице со следующими доступными параметрами.

iFrameResize({
    log                    : true,  // For development
    autoResize             : true,  // Trigering resize on events in iFrame
    contentWindowBodyMargin: 8,     // Set the default browser body margin style (in px)
    doHeight               : true,  // Calculates dynamic height
    doWidth                : false, // Calculates dynamic width
    enablePublicMethods    : true,  // Enable methods within iframe hosted page 
    interval               : 32,    // interval in ms to recalculate body height, 0 to disable refreshing
    scrolling              : false, // Enable the scrollbars in the iFrame
    callback               : function(messageData){ // Callback fn when message is received
        $('p#callback').html(
            '<b>Frame ID:</b> '    + messageData.iframe.id +
            ' <b>Height:</b> '     + messageData.height +
            ' <b>Width:</b> '      + messageData.width + 
            ' <b>Event type:</b> ' + messageData.type
        );
    }
});

вместо использования scroll=no на iframe, я меняю его на"auto". Затем я получаю размер фактического окна

$(window).height();

и использовать его в качестве атрибута высоты iframe.

Ну и результат есть...

у нас никогда не будет прокрутки "страницы", только прокрутка "iframe". При навигации не имеет значения, кто является свитком, но важно, что есть только 1.

Ну, есть проблема пользователя просто изменить размер окна, пока он навигация. Чтобы решить эту проблему, я использую:

setInterval(getDocHeight, 1);

ты думаешь, что это решение вызовет какие-либо ошибки? Он работает для меня, и на iFrame у меня был динамический contect, сгенерированный php. Я боюсь будущих ошибок с этим...

В настоящее время есть только 4 решения, которые я знаю:

только третий может решить многие проблемы. Например вы можете создать отзывчивый iFrame; закройте его изнутри или вы можете общаться с ним. Но для этого вам нужен iframe в Iframe и обходной путь "сторонние куки" (необязательно).

Я создал статью об этом с Пример: управляемый событиями междоменный iFrame

вы изучили атрибуты HTML5' object-fit'? Масштабирование видео / изображений в iframe, а не масштабирование iframe (хорошо, если вы берете изображение среднего размера, которое в конечном итоге составляет 5 000 пикселей в ширину). Опция" fit "(другие-" обложка "и" заливка") использует подход типа letterbox для подгонки источника при сохранении пропорций. Для просмотра HTML5-less там, похоже, есть много доступных полифиллов. Это здорово, но ошибка на краю имеет держал его несовместимым с новым кошмаром Microsoft около года, теперь:https://github.com/anselmh/object-fit

EDIT: чтобы обойти проблемы с кросс-доменом, вы всегда можете просто выполнить работу в скрипте содержимого расширения Chrome, поскольку он считает, что это часть страницы, на которую вы вставляете свой iframe.

HTTPS еще одна ссылка получить высоту iframe autoheight

https://-a.com Содержание:

 <!DOCTYPE html>
    <html>
    <head>
        <title>Test Page</title>
    </head>
    <body>
        Test Page:
        <hr/>
        <iframe id="iframe" src="https://-b.com" style="width:100%;min-height:600px;border:none;" scrolling="no" ></iframe>
        <script>
        // browser compatibility: get method for event 
        // addEventListener(FF, Webkit, Opera, IE9+) and attachEvent(IE5-8)
        var myEventMethod = 
            window.addEventListener ? "addEventListener" : "attachEvent";
        // create event listener
        var myEventListener = window[myEventMethod];
        // browser compatibility: attach event uses onmessage
        var myEventMessage = 
            myEventMethod == "attachEvent" ? "onmessage" : "message";
        // register callback function on incoming message
        myEventListener(myEventMessage, function (e) {
            // we will get a string (better browser support) and validate
            // if it is an int - set the height of the iframe #my-iframe-id
            if (e.data === parseInt(e.data)) 
                document.getElementById('iframe').height = e.data + "px";
        }, false);
        </script>
    </body>
    </html>

https://-b.com Содержание iframe:

<!DOCTYPE html>
<html>
<head>
    <title>Test Iframe Content</title>
    <script type="text/javascript">
    // all content including images has been loaded
    window.onload = function() {
        // post our message to the parent
        window.parent.postMessage(
            // get height of the content
            document.body.scrollHeight
            // set target domain
            ,"*"
        )
    };
</script>
</head>
<body>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>1
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>2
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>3
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>4
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>5
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>6
</body>
</html>

Таблица Работы:

XCOM http > ycom https WORK

XCOM https > ycom https WORK

XCOM http > ycom http WORK

XCOM https > ycom http Работа

Test Work Screenshot

вы хотите найти высоту страницы, содержащейся в iframe? У меня есть некоторые JavaScript, который проверяет высоту содержимое iframe затем задает высоту кадра по высоте содержимого.

var Height = document.getElementById('iFrameId').contentWindow.document.body.scrollHeight;

document.getElementById('iFrameId').height = Height;

однако это работает только в том случае, если страница, которую вы показываете в iframe, находится в том же домене. Если это не так, вы не можете получить доступ к необходимой информации. Следовательно, ошибка отказа в доступе.

чтобы изменить размер iframe, вот простой скрипт:

это идет в голову: (это было написано для PHP-скрипта, для html, измените 'to" и \ " to '...

<script type='text/javascript'>
<!--
function resizeIframe(id){
/*
this.obj=obj
//this.obj.width=null
//this.obj.width=window.frames[\"sizeframe1\"].document.body.scrollWidth
this.obj.style.height=\"\" // for Firefox and Opera
setTimeout(\"this.obj.style.height=this.obj.contentWindow.document.body.scrollHeight+(notIE?heightOffset:0)\",10) // setTimeout required for Opera
*/

el=document.getElementById(id)
el.style.height='200px' // for Firefox and Opera
setTimeout('el.style.height=el.contentWindow.document.body.scrollHeight+\"px\"',1) // setTimeout required for Opera
}

// -->
</script>"

конец главы

это идет в теле (помните, что это было написано для PHP-скрипта, для html измените все ' to " и \" to '...)

<iframe onload='resizeIframe(this.id)' allowTransparency=\"true\" name='ccpaymentwindow' id='sizeframe1' marginwidth='1' marginheight='1' height='700' width='690' border='0' frameborder='1' scrolling='no' src='ccmslink.php?variable1=" . $variable1 . "'></iframe>

бонус: есть некоторые подсказки выше. Поскольку он установлен для сценариев php, вы можете многое сделать с помощью it...to узнайте больше, сделайте больше...

ключ к этому- "sizeframe1".... для нескольких "resizers" на одной странице скопируйте один и тот же скрипт, но измените идентификатор в iframe и имя в скрипте в голове, и viola! у вас есть несколько размеров на одном и том же page...it работает очень хорошо!

есть phun.

Comments

    Ничего не найдено.