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 
теперь, как 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/
изменить 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+.
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 решения, которые я знаю:
- postMessage. некоторые браузеры не поддерживаются конечно.
- окно.местоположение.хеш-манипуляции. Я думаю, что это решение № 2 здесь.
- easyXDM
- window.name транспорт
только третий может решить многие проблемы. Например вы можете создать отзывчивый 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 Работа
вы хотите найти высоту страницы, содержащейся в 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