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

Как получить исходный источник innerHTML без содержимого, сгенерированного Javascript?

Можно ли каким-либо образом получить исходный HTML-источник без изменений, сделанных обработанным Javascript? Например, если я:

<div id="test">
    <script type="text/javascript">document.write("hello");</script>
</div>

Если я это сделаю:

alert(document.getElementById('test').innerHTML);

он показывает:

<script type="text/javascript">document.write("hello");</script>hello

Проще говоря, я хотел бы, чтобы alert отображался только:

<script type="text/javascript">document.write("hello");</script>

без окончательного hello (результат обработанного script).

4b9b3361

Ответ 1

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

Вы можете обернуть интересующий раздел внутри "замороженного" script:

<script id="frozen" type="text/x-frozen-html">

Атрибут type, который я только что составил, но заставит браузер игнорировать все, что внутри него. Затем вы добавляете еще один тег script (соответствующий javascript на этот раз) сразу после этого - "оттаивание" script. Это оттаивание script получит замороженный script по идентификатору, возьмет текст внутри него и сделает document.write, чтобы добавить фактическое содержимое на страницу. Всякий раз, когда вам нужен исходный источник, он по-прежнему сохраняется как текст внутри замороженного script.

И у вас это есть. Недостатком является то, что я не буду использовать его для всей страницы... (SEO, подсветка синтаксиса, производительность...), но это вполне приемлемо, если у вас есть специальное требование на части страницы.


Изменить: Вот пример кода. Кроме того, как правильно указал @FlashXSFX, любые теги script внутри замороженного script должны быть экранированы. Поэтому в этом простом примере для этой цели я создаю тег <x-script>.

<script id="frozen" type="text/x-frozen-html">
   <div id="test">
      <x-script type="text/javascript">document.write("hello");</x-script>
   </div>
</script>
<script type="text/javascript">
   // Grab contents of frozen script and replace `x-script` with `script`
   function getSource() {
      return document.getElementById("frozen")
         .innerHTML.replace(/x-script/gi, "script");
   }
   // Write it to the document so it actually executes
   document.write(getSource());
</script>

Теперь, когда вам нужен источник:

alert(getSource());

См. демонстрацию: http://jsbin.com/uyica3/edit

Ответ 2

Не могли бы вы отправить запрос Ajax на ту же страницу, на которой вы сейчас находитесь, и использовать результат в качестве исходного HTML? Это безупречно, учитывая правильные условия, поскольку вы буквально получаете исходный HTML-документ. Однако это не будет работать, если страница будет изменяться при каждом запросе (с динамическим контентом) или если по какой-либо причине вы не сможете сделать запрос на эту конкретную страницу.

Ответ 3

Простым способом является получение его снова на сервере. Скорее всего, это будет в кеше. Вот мое решение, используя jQuery.get(). Он берет оригинальный uri страницы и загружает данные с помощью ajax-вызова:

$.get(document.location.href, function(data,status,jq) {console.log(data);})

Это будет печатать исходный код без javascript. Он не выполняет обработку ошибок!

Если вы не хотите использовать jQuery для извлечения источника, обратитесь к этому вопросу: Как сделать вызов ajax без jquery?

Ответ 4

Подход грубой силы

var orig = document.getElementById("test").innerHTML;
alert(orig.replace(/<\/script>[.\n\r]*.*/i,"</script>"));

EDIT:

Это может быть лучше

var orig = document.getElementById("test").innerHTML + "<<>>";
alert(orig.replace( /<\/script>[^(<<>>)]+<<>>/i, "<\/script>"));

Ответ 5

Если вы переопределите document.write, чтобы добавить некоторые идентификаторы в начале и в конце всего, написанного в документе с помощью script, вы сможете удалить эти записи с регулярным выражением.

Вот что я придумал:

    <script type="text/javascript" language="javascript">
        var docWrite = document.write;
        document.write = myDocWrite;

        function myDocWrite(wrt) {
            docWrite.apply(document, ['<!--docwrite-->' + wrt + '<!--/docwrite-->']);
        }
    </script>

Добавил ваш пример где-то на странице после начального script:

    <div id="test">
        <script type="text/javascript">     document.write("hello");</script>
    </div>

Затем я использовал это, чтобы предупредить, что внутри:

    var regEx = /<!--docwrite-->(.*?)<!--\/docwrite-->/gm;
    alert(document.getElementById('test').innerHTML.replace(regEx, ''));

Ответ 6

Если вы хотите получить нетронутый документ, вам нужно его снова забрать. Нет. Если бы не document.write() (или аналогичный код, который будет выполняться во время процесса загрузки), вы можете загрузить исходный документ innerHTML в память на load/domready, прежде чем изменять его.

Ответ 7

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

Ближайшим, о котором я могу думать, добиться того, что вы хотите, является использование Ajax для загрузки новой копии необработанного HTML для вашей страницы в строку Javascript, после чего с нее вы можете делать то, что вам нравится, включая отображение его в окне предупреждения.

Ответ 8

Сложным способом является использование тега <style> для шаблона. Так что вам больше не нужно переименовывать x-script.

console.log(document.getElementById('test').innerHTML);
<style id="test" type="text/html+template">
    <script type="text/javascript">document.write("hello");</script>
</style>

Ответ 9

Я думаю, вы хотите пересечь узлы DOM:

var childNodes = document.getElementById('test').childNodes, i, output = [];

for (i = 0; i < childNodes.length; i++)
    if (childNodes[i].nodeName == "SCRIPT")
        output.push(childNodes[i].innerHTML);

return output.join('');