如何在没有Javascript生成内容的情况下获取原始的innerHTML源代码?

时间:2010-12-09 11:14:08

标签: javascript html innerhtml

是否有可能以某种方式原始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(已处理脚本的结果)。

9 个答案:

答案 0 :(得分:6)

我不认为有一个简单的解决方案只是“抓取原始资源”,因为它必须是浏览器提供的东西。但是,如果您只对页面的某个部分感兴趣,那么我有一个解决方法。

您可以将感兴趣的部分包装在“冻结”脚本中:

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

我刚刚编写的type属性,但它会强制浏览器忽略其中的所有内容。然后,在此之后立即添加另一个脚本标记(这次正确的javascript) - “解冻”脚本。这个解冻脚本将通过ID获取冻结的脚本,获取其中的文本,然后执行document.write将实际内容添加到页面。每当您需要原始源时,它仍然会在冻结脚本中作为文本捕获。

你有它。缺点是我不会在整个页面中使用它...(搜索引擎优化,语法突出显示,性能......)但如果你对页面的某个部分有特殊要求,这是完全可以接受的。


编辑:这是一些示例代码。此外,正如@FlashXSFX正确指出的那样,冻结脚本中的任何脚本标记都需要进行转义。因此,在这个简单的示例中,我将为此目的组成一个<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

答案 1 :(得分:3)

一种简单的方法是再次从服务器获取它。它最有可能在缓存中。这是我使用jQuery.get()的解决方案。它需要页面的原始uri并使用ajax调用加载数据:

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

这将打印原始代码,无需任何JavaScript。它没有做任何错误处理!

如果您不想使用jQuery获取源代码,请参阅此问题的答案:How to make an ajax call without jquery?

答案 2 :(得分:2)

您是否可以将Ajax请求发送到您当前所在的同一页面并将结果用作原始HTML?在适当的条件下,这是万无一失的,因为您实际上是获取原始HTML文档。但是,如果页面在每个请求(包含动态内容)上发生更改,或者由于某种原因您无法向该特定页面发出请求,则此操作无效。

答案 3 :(得分:1)

蛮力方法

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

编辑:

这可能会更好

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

答案 4 :(得分:0)

如果覆盖document.write以在脚本写入文档的所有内容的开头和结尾添加一些标识符,则可以使用正则表达式删除这些写入。

以下是我提出的建议:

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

        function myDocWrite(wrt) {
            docWrite.apply(document, ['<!--docwrite-->' + wrt + '<!--/docwrite-->']);
        }
    </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, ''));

答案 5 :(得分:0)

如果您需要原始文档,则需要再次获取它。没有办法解决这个问题。如果不是document.write()(或在加载过程中运行的类似代码),则可以在修改之前将原始文档的innerHTML加载到内存中加载/ domready。

答案 6 :(得分:0)

我想不出一个可以按你要求的方式工作的解决方案。 Javascript可以访问的唯一代码是通过DOM,它只包含页面处理后的结果。

我能想到的最接近你想要的就是使用Ajax将页面原始HTML的新副本下载到Javascript字符串中,此时因为它是一个字符串,你可以用它做任何你喜欢的事情,包括在警告框中显示它。

答案 7 :(得分:0)

一种棘手的方法是使用<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>

但我不喜欢这个丑陋的解决方案。

答案 8 :(得分:-1)

我认为你想要遍历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('');