2014-02-26 20 views
9

我在PHP中使用HTML Tidy,並且由於JavaScript字符串文字中的<script>標記而產生意外結果。這裏有一個樣本輸入:HTML Tidy在JavaScript字符串文字中的腳本標記上失敗

<html> 
<script> 
var t='<script><'+'/script>'; 
</script> 
</html> 

HTML整潔的輸出:

<html> 
<script> 
//<![CDATA[ 
var t='<script><'+'/script>'; 
<\/script> 
<\/html> 
//]]> 
</script> 
</html> 

它解釋</script></html>作爲腳本的一部分。然後,它會添加另一個</script></html>以關閉打開的標記。我在HTML Tidy的一個在線版本(http://www.dirtymarkup.com/)上試過這個,並且它產生了同樣的錯誤。

如何防止在PHP中發生此錯誤?

+3

我會說「打開bug票」,但他們沒有任何意味着在他們的網站上這樣做... – akonsu

+0

i一個有趣的錯誤,但似乎非常具體的關閉腳本標記,我只是使用你當前的解決方案..也用於輸出<和/腳本>分別迷惑我 – clancer

+0

你可以指定爲什麼你想添加腳本標記到一個變量。 –

回答

6

玩弄這一點後,我發現了一個可以使用註釋//'<\/script>'迷惑算法的方式來防止這種錯誤的發生:

<html> 
<script> 
var t='<script><'+'/script>'; //'<\/script>' 
</script> 
</html> 

後清理:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> 

<html> 
<head> 

    <script> 
var t='<script><'+'/script>'; //'<\/script>' 
    </script> 

    <title></title> 
</head> 

<body> 
</body> 
</html> 

我的猜測是,由於清理算法通過代碼查找並檢測到字符串<script>兩次,它立即尋找</script>。並且</script>分離使得第二個</script>未被檢測到,這就是爲什麼它決定在代碼的末尾添加另一個</script>並且以某種方式還以antoher </html>關閉它。 (可憐的設計確實!)

所以我做了第二個假設,在算法中沒有if語句來確定</scirpt>是否在註釋中,而我是對的!將另一個字符串<\/script>作爲javascript註釋確實使算法認爲總共有兩個</script>

0

儘量使腳本標籤不是一個完整的字,但字符串連接

<html> 
<script> 
var t='<scr'+'ipt><'+'/script>'; 
</script> 
</html> 

得到的清潔代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> 

<html> 
<head> 

    <script> 
var t='<scr'+'ipt><'+'/script>'; 
    </script> 

    <title></title> 
</head> 

<body> 
</body> 
</html> 
0

這可能是一個更好的做法是創建這樣一個腳本標籤: (這也應該解決你的整潔問題)

<script> 
    script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = 'http://myserver.com/file.js'; 
    document.getElementsByTagName('head')[0].appendChild(script); 
</script> 
0

單程i s使它整潔不檢測腳本標記。我能想出的「最乾淨」的方式是逃避標籤中的角色。

<html> 
<script> 
var t='<\script><'+'/script>'; 
</script> 
</html> 

,所以你甚至可以做到這一點,而不必打破串起來如上:

var t='<\script></\script>'; 
1

沒有必要爲字符串連接,以避免關閉</script>。簡單地轉義/字符足以「傻瓜」在瀏覽器中的解析器和,看來,HTML整潔的解析器,以及:

<html> 
<script> 
var t='<script><\/script>'; 
</script> 
</html> 
0

這只是按預期工作

<html> 
    <script> 
     var t='<'+'script><'+'/script>'; 
    </script> 
</html> 

順便說一句,串連接並不是最好的方式來創建動態的HTML插入頁面,尋找document.createElement,甚至模板引擎(handlebars.js是我最喜歡的)