it-roy-ru.com

Как добавить код JavaScript в существующий iFrame, используя jQuery?

Я хочу добавить фрагмент JavaScript в существующий iFrame на странице, используя jQuery. У меня есть следующий код ...

Код:

content = "<script>" + js_code + "</script>";

$('#iframe_id').contents().find('body').append(content);

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

12
Gandalf

Проблема в том, что анализатор HTML запутывается, если в вашем скрипте есть закрывающий тег скрипта (</script>), и он преждевременно закрывает тег скрипта.

Решение состоит в том, чтобы избежать / в "<\/script>". Это работает, потому что строки в JavaScript (и некоторых других языках), любые недопустимые escape-последовательности просто игнорируются, поэтому "\l" рассматривается как "l", а "\/" обрабатывается как "/". Однако анализатор HTML не использует обратную косую черту, чтобы избежать их, чтобы он не запутался (предоставлено https://stackoverflow.com/users/405681/keaukraine ).

var scriptTag = "<script>alert(1)<\/script>";
$("#iframe").contents().find("body").append(scriptTag);

Оригинальный способ решения

Разбейте этот закрывающий тег, чтобы не испортить HTML-парсер. Другие решения на этой странице работают, потому что в их коде никогда нет строки </script>

var scriptTag = "<script>alert(1)<";
scriptTag +=  "/script>";
console.log(scriptTag);
$("#iframe").contents().find("body").append(scriptTag);

http://jsfiddle.net/ALpjZ/2/

17
Juan Mendes
function putScriptInIframes(script, scriptId) {

   var $iframes = $('iframe');
   $iframes.each(function () {
        var thisDoc = this.contentWindow.document;
        if ( ! thisDoc.getElementById(scriptID)) {
            var scriptObj = thisDoc.createElement("script");
            scriptObj.type = "text/javascript";
            scriptObj.id = scriptId;
            scriptObj.innerHTML = script;
            thisDoc.body.appendChild(scriptObj);
        }
    });
}

Это был самый простой способ заставить это работать. 

4
Dan B
var script = "alert('hello world');";
$('#iframe').contents().find('body').append($('<script>').html(script))

работает в Fiddle

4
Neil S

Вам нужно экранировать /script. Он появляется.

Вам нравится Google Analytics, например

 $("#iframe").contents().find("body").append(decodeURI("**%3Cscript%3E** alert(2)  **%3C/script%3E**")); 

замените script и /script на эти экранированные

Надеюсь, поможет.

3
Bruno Braga

Поскольку iframe работает как свой собственный window, вам также придется внедрить импорт файла jquery.js.

<script type="text/javascript" src="/jquery/jquery-ui-1.9.1.custom.js"></script>

EDIT: Так что я играл с этим немного больше, и вот что я придумал.

HTML

<iframe id="frame"></iframe>

JS

$("#frame").attr(
   "src", "data:text/html;charset=utf-8," + 
   "<html>" + 
   "<style>.red {color: red}</style>" + 
   "<div class=\"test\">Test</test>" + 
   "<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"><" + "/script>" +    
   "<script>$(function(){ $(\".test\").addClass(\"red\")});<" + "/script>" +         
   "</html>"
);

Это работает, смотрите здесь http://jsfiddle.net/WsCxj/ .

Итак, есть несколько моментов:

  1. Я передаю весь контент в одну строку. Вы должны добавить data:text/html;charset=utf-8,, а затем установить строку как src для iframe.

  2. Я добавляю файл jquery.js с абсолютным путем - Это кажется важным, вероятно, потому что фрейм не имеет пути сам по себе, поскольку его содержимое генерируется динамически.

  3. Я разделил тэг end script как этот <" + "/script>, потому что по крайней мере firefox пытается завершить реальный скрипт на этом этапе. Более чистый подход, вероятно, будет иметь js как совершенно отдельный файл.

2
ced-b

Вам не нужно добавлять скрипт тега для выполнения JavaScript, вы можете сделать функцию и применить контекст iframe ...

используя Eval

function initFrame (code){

    eval (code);

}

initFrame.apply ($('#iframe').contents(),[js_code]);

Без оценки

var initFrame = new Function(js_code);


initFrame.apply ($('#iframe').contents(),[]);
1
Luan Castro

Я не могу комментировать ваш последний пост, потому что я новичок здесь, и у меня недостаточно репутации, но, как я уже говорил в своем посте, проблема была в/script.

Так что избежать этого (как, например, делает Google), возможно, является лучшим вариантом ...

Что ж, хорошая новость в том, что проблема решена;)

С уважением

0
Bruno Braga