簡體   English   中英

如何在沒有Javascript生成內容的情況下獲取原始的innerHTML源代碼?

[英]How do I get the original innerHTML source without the Javascript generated contents?

是否有可能以某種方式獲取原始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 id="frozen" type="text/x-frozen-html">

我剛剛編寫的type屬性,但它會強制瀏覽器忽略其中的所有內容。 然后,在此之后立即添加另一個腳本標記(這次正確的javascript) - “解凍”腳本。 這個解凍腳本將通過ID獲取凍結的腳本,獲取其中的文本,並執行document.write將實際內容添加到頁面。 每當您需要原始源時,它仍然作為凍結腳本內的文本捕獲。

你有它。 缺點是我不會在整個頁面中使用它...(SEO,語法高亮,性能......)但如果你對頁面的某個部分有特殊要求,這是完全可以接受的。


編輯:這是一些示例代碼。 此外,正如@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

一種簡單的方法是再次從服務器獲取它。 它最有可能在緩存中。 這是我使用jQuery.get()的解決方案。 它需要頁面的原始uri並使用ajax調用加載數據:

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

這將打印原始代碼,沒有任何JavaScript。 它沒有做任何錯誤處理!

如果不想使用jQuery來獲取源代碼,請參考這個問題的答案: 如何在沒有jquery的情況下進行ajax調用?

您是否可以將Ajax請求發送到您當前所在的同一頁面並將結果用作原始HTML? 在適當的條件下,這是萬無一失的,因為您實際上是獲取原始HTML文檔。 但是,如果頁面在每個請求(包含動態內容)上發生更改,或者由於某種原因您無法向該特定頁面發出請求,則此操作無效。

蠻力方法

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

如果覆蓋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, ''));

如果您需要原始文檔,則需要再次獲取它。 沒有辦法解決這個問題。 如果不是document.write()(或者在加載過程中運行的類似代碼),則可以在修改之前將原始文檔的innerHTML加載到內存中加載/ domready。

我想不出一個可以按照你要求的方式工作的解決方案。 Javascript可以訪問的唯一代碼是通過DOM,它只包含頁面處理后的結果。

我能想到的最接近你想要的就是使用Ajax將頁面的原始HTML的新副本下載到Javascript字符串中,此時因為它是一個字符串,你可以隨意做任何事情,包括顯示它在警報框中。

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

但我不喜歡這個丑陋的解決方案。

我想你想遍歷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('');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM