Подтвердить что ты не робот

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

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

-Edit

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

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

Чтобы сэкономить ваше время, даже не спускайтесь по этому маршруту, просто используйте sendMessages для междоменной связи. Есть плагины для HTML <5, что я use- Перейти к нижней части для приятного примера :)


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

3 фрейма

Самое близкое решение, которое я нашел, было 3 iframes-, но оно имеет умный хром и сафари, поэтому я не могу использовать это.

открытый в хромированном состоянии

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

Измерение полос прокрутки

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

document.body.scrollHeight

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

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

$('#frameId').Height()

$('#frameId').clientHeight

$('#frameId').scrollHeight

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

Вычислительные стили

Но если я проверю и элемент в chrome iframe, он bladdy показывает мне размеры документов внутри iframe (используя jquery x-domain, чтобы получить iframe.heigh - доступ запрещен). В вычисленном CSS enter image description here ничего нет,

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

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.. и это не идеальная ситуация для коммерческих лиц... и некоторые invoke чистые java-апплеты или серверная визуализация

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

http://htmlunit.sourceforge.net/ <-java не jscript

http://maxq.tigris.org/


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

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

ВАРИАНТ 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, если размер изменился и отправляется только в том случае, если изменения размеров являются отправкой сообщений каждые 500 мс. Если вы выполните эту проверку, вы можете изменить опрос до 50 мс! повеселись


Работайте в браузерах и быстро. Отличные функции отладки!

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

Решение 2 (работает, но не очень хорошо)

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

Таким образом, в другой домен будут включены теги 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>

В 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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Это комбинация моего кода и решения David. Мое решение специально предназначено для изменения размера 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>

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

Бест, Baker

Ответ 3

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

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
        );
    }
});

Ответ 4

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

$(window).height();

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

Ну, результат...

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

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

setInterval(getDocHeight, 1);

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

Ответ 5

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

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

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

Ответ 6

Вы изучали атрибуты HTML5, подходящие для объекта? Масштабирует видео/изображения в iframe, а не масштабирует iframe (приятно, если вы захватите изображение среднего размера, которое заканчивается шириной 5000 пикселей). Опция "подгонка" (другие - "обложка" и "заполнение" ) использует подход с сортировкой букв, чтобы соответствовать источнику при сохранении пропорций. Для просмотра HTML5-less там, похоже, есть много полипов. Это замечательно, но ошибка на конце Edge сохранила его несовместимо с Microsoft New Nightmare в течение года, теперь: https://github.com/anselmh/object-fit p >

РЕДАКТИРОВАТЬ. Чтобы обойти проблемы с перекрестным доменом, вы всегда можете просто выполнять работу с содержимым внутреннего содержимого Chrome Script, так как он считает его частью страницы, на которой вы прикрепляете ваш iframe.

Ответ 7

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

https:/ / -a.com content:

 <!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 content:

<!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 РАБОТА

xcom http> ycom http WORK

xcom https> ycom http WORK

Test Work Screenshot

Ответ 8

Вы хотите найти высоту страницы, содержащейся в iframe? Я получил некоторую работу javascript, которая проверяет высоту содержимого iframe, а затем устанавливает высоту iframe в высоту содержимого.

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

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

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

Ответ 9

Чтобы изменить размер iframe, здесь просто script:

это идет в голову: (это было написано для php script, для html, измените "на" и "на"...

<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 script, для html измените все "на" и "на"...)

<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, вы можете много сделать с ним... узнать больше, сделать больше...

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

имеют phun.