Вопрос по iframe, javascript, jquery – Почему jQuery удаляет теги body и head при заполнении iframe тегом style, но не без него?

7

Если я запускаю следующий код, теги body и head будут удалены.

<code><iframe src='blank.htm'>
    <html>
    <head>
        <style type="text/css">

        </style>
    </head>
    <body>
        test
    </body>
    </html>
</iframe>
<script>
    $('iframe').load(function () {
        var contents = $('iframe').text();
        $('iframe').contents().find('html').html(contents);
    });
</script>
</code>

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

Я создаю «песочницу», которая позволит мне правильно отображать HTML-шаблон для конечного пользователя. Подумайте о предварительном просмотре электронного письма, в котором вам нужно увидеть конечный результат в другом веб-окне. Без песочницы вы бы навязывали другие стили и форматы, которые не являются частью содержимого сообщения, а также наоборот. Этот код позволяет мне заполнить iframe, как только он окажется на странице, не затрагивая остальную часть моего кода или саму страницу. Middletone
Хорошо, имеет смысл! Это помогает поставить проблему в контекст для нас. +1. Подумайте о слиянии информации в поле вашего вопроса выше :) Интересный вопрос! jmort253
Почему вы это делаете? Можете ли вы уточнить? Быстрый ответ коленного рефлекса, который приходит на ум, - «не делай этого», но я подозреваю, что есть причина, почему ты делаешь это, о чем ты нам не говоришь? :) Я думаю, что мы можем помочь, если ты скажешь нам, какова твоя цель. Удачи! jmort253
Это панель предварительного просмотра, поэтому контент не обязательно должен постоянно находиться где-либо еще в данный момент, поэтому я не просто загружаю другую страницу с информацией. Middletone

Ваш Ответ

2   ответа
3

Вот шаги, которые вы можете выполнить, чтобы получить представление о том, как скопировать содержимое iframe в строку, изменить его и заменить в iframe. Эти шаги предназначены для выполнения в вашем Chrome Debugger и предназначены только для образовательных / демонстрационных целей. Как только вы поймете этот процесс, вы сможете попытаться повторить его в своем коде на своем веб-сайте.

Run each function one at a time in Chrome Debugger:

// test iframe I loaded in a sandbox also at http://example.com
$('body div:first').before('<iframe src="http://example.com/company"></iframe>');

// retrieved the body of the iframe - I cloned it so I could perform operations
  // on the copy without bothering the iframe content.
iBody = $('iframe:first').contents().find('body').clone();

// got the head
iHead = $('iframe:first').contents().find('head').html();

// if there is script in the body, it really messes things up. So in my tests, 
  // I had to remove it before adding it back to the iframe.
iBody.find("script").remove();

// verify there are no script elements
ibody.html(); 

// replace the iframe head
$('iframe:first').contents().find('head').html(iHead);

// replace the iframe body first with a placeholder. The body is the sensitive 
  // part. If you destroy the DOM, it can make the entire page, including 
    // the parent, turn completely white.
$('iframe:first').contents().find('body').html('<div></div>');

// ** inserted something in the copy to prove we modified it!!
iBody.append("<div style='position:absolute;z-index:5000; color:red; " + 
    "background-color:white;'>JAMES WAS HERE</div>");

// now replace the body
$('iframe:first').contents().find('body').html(iBody);

In the bottom of the website, inside the iframe, I saw my message in red on a white background. I could also see it in the source:

$('iframe:first').contents().find('body').html();

Я выполнил эти действия на анонимном веб-сайте, используя консоль отладчика Chrome для запуска команд. Первая команда создает iframe на домашней странице со страницей компании сайта в iframe. Оставшиеся команды получают заголовок и тело этого iframe, клонируют тело, добавляют некоторые вещи, такие как «ДЖЕЙМС БЫЛ ЗДЕСЬ» сообщение к клону body, а затем замените тело iframe этой копией.

Я также подтвердил те же результаты, загрузивhttp://getsatisfaction.com в моем браузере и загрузкаhttp://getsatisfaction.com/explore/product-innovation в фрейме. Повторив описанные выше шаги, я увидел свое сообщение «ДЖЕЙМС БЫЛ ЗДЕСЬ».

** Самой серьезной проблемой, с которой я столкнулся, было отсутствие возможности оставлять теги JavaScript или CSS-стиля в копии. Решение для стилизации состоит в том, чтобы сделать все модификации стиляbefore добавление тела обратно в iframe. **

По какой-то причине браузер пытался запустить JavaScript и выкидывал ошибки. Контекст этих ошибок заставил меня подумать, что JavaScript запускается в контексте верхнего уровня, а не в контексте iframe! Это может быть для вас показом. Возможно, вам придется придумать другой план для отображения предварительного просмотра во всплывающем окне или в строке. Кроме того, это может вести себя по-разному на разных сайтах с разным JavaScript. Это также может вести себя странно в IE.

Короче говоря, я не вижу, чтобы это решение поддерживало производственный веб-сайт, поскольку JavaScript должен быть удален в iframe; однако, в зависимости от ваших потребностей, возможно, что эта работа будет работать в производственном режиме, если вам не понадобится DOM iframe для использования какого-либо JavaScript.

Тем не менее, это была интересная проблема для изучения!

16

У меня была такая же проблема, и я узнал отэтот ТАК вопрос на самом деле это браузер, который выполняет зачистку, как часть его анализаinnerHTML собственность, которая есть чтоjQuery использует внутри.html().

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

Тогда к решению. Это так же просто, как установитьinnerHTML собственностьhtml элемент напрямую, вот так:

// This forcibly removes head, body, and other tags, since it internally uses an empty DIV and its innerHTML property
jQuery(targetElement).html(exitHtml);

// This works fine
h = document.getElementsByTagName('html')[0];
h.innerHTML = htmlString;

Для вашего конкретного случая просто нацельтесь наhtml элементinside iframe. Your final code might be:

<script>
    $('iframe').load(function () {
        var contents = $('iframe').text();
        iframeHtml = $('iframe').contents().find('html').get(0);
        iframeHtml.innerHTML = contents;
    });
</script>
Отличный ответ .. Я также почесал голову об этом ...
@Middletone ИМХО это должен быть принят ответ.
Согласовано. Это решает проблему, тогда как принятый ответ - технически интересное путешествие, но не ответ.

Похожие вопросы