[toc]
# 簡述
HTML 優(yōu)雅明了,但要是出了錯,你會不會一頭霧水呢,本節(jié)將介紹一些查找和修復(fù) HTML 錯誤的工具。
# 調(diào)試并不可怕
寫代碼通常都是按部就班的,但是一旦犯了錯,可怕的代碼問題就出現(xiàn)了:或徹底罷工,或得不到正確結(jié)果。比如,以下窗口顯示了:用 [Rust](https://www.rust-lang.org/) 編寫的一個小程序在[編譯](https://developer.mozilla.org/zh-CN/docs/Glossary/%E7%BC%96%E8%AF%91)時得到的出錯信息:
![圖片描述](/upload/attach/202011/202011301702_CMEHRYCTSGCEDU7.png)
這里錯誤信息比較容易理解:"unterminated double quote string",即"雙引號字符串未閉合"。錯誤列表中可以看到 println!(Hello, world!"); 這里少一個雙引號,然而當(dāng)程序規(guī)模變大時,錯誤信息也會變得更復(fù)雜和更難解釋,同時對于 Rust 新手而言,上述提示也是找不到北。
調(diào)試其實沒有那么可怕,寫代碼和調(diào)試的關(guān)鍵其實是:熟悉語言本身和相關(guān)工具。
# HTML 和調(diào)試
HTML 并不像 Rust 那么難以理解,瀏覽器并不會將 HTML 編譯成其它形式,而是直接解析并顯示結(jié)果(稱之為解釋,而非編譯)。可以說 HTML 的 元素 語法比 Rust、JavaScript 或 Python 這樣“真正的編程語言”更容易理解。瀏覽器解析 HTML 的過程比編程語言的編譯運(yùn)行的過程要寬松得多,但這是一把雙刃劍。
## 寬松的代碼
寬松是什么意思呢?通常寫錯代碼會帶來以下兩種主要類型的錯誤:
* 語法錯誤:由于拼寫錯誤導(dǎo)致程序無法運(yùn)行,就像上面的 Rust 示例。通常熟悉語法并理解錯誤信息后很容易修復(fù)。
* 邏輯錯誤:不存在語法錯誤,但代碼無法按預(yù)期運(yùn)行。通常邏輯錯誤比語法錯誤更難修復(fù),因為無法得到指向錯誤源頭的信息。
HTML 本身不容易出現(xiàn)語法錯誤,因為瀏覽器是以寬松模式運(yùn)行的,這意味著即使出現(xiàn)語法錯誤瀏覽器依然會繼續(xù)運(yùn)行。瀏覽器通常都有內(nèi)建規(guī)則來解析書寫錯誤的標(biāo)記,所以即使與預(yù)期不符,頁面仍可顯示出來。當(dāng)然,是存在隱患的。
**注:**
```
HTML 之所以以寬松的方式進(jìn)行解析,是因為 Web 創(chuàng)建的初心就是:人人可發(fā)布內(nèi)容,不去糾結(jié)代碼語法。如果 Web 以嚴(yán)格的風(fēng)格起步,也許就不會像今天這樣流行了。
```
##主動學(xué)習(xí):研究寬容的代碼風(fēng)格
現(xiàn)在來研究 HTML 代碼的寬松特性。
* 首先,下載并保存 debug-example.html。代碼中故意留了一些錯誤,以便探究(這里的 HTML 標(biāo)記寫成了 糟糕的格式,與 良好的格式 相反)。
* 下一步,在瀏覽器中打開,可以看到:
![圖片描述](/upload/attach/202011/202011301704_6JG3K78XFDDXNVK.png)
* 看起來糟透了,我們到源代碼中尋找原因(只列出 body 部分):
```
<h1>HTML 調(diào)試示例</h1>
<p>什么使得 HTML 出錯?
<ul>
<li>未閉合的元素:如果元素<strong>沒有正確的結(jié)束標(biāo)記,那么將影響下方整個區(qū)域,這不是你期望的。
<li>錯誤嵌套元素:正確進(jìn)行嵌套是一項重要的編碼習(xí)慣。<strong>重點(strong)<em>重點強(qiáng)調(diào)(strongly emphasised)?</strong>這又是什么鬼?</em>
<li>未閉合的屬性:另一種 HTML 常見錯誤。來看一個示例:<a href="https://www.mozilla.org/>Mozilla 主頁鏈接</a>
</ul>
```
* 以下是問題清單:
```
1.段落(Paragraph) 和 列表項(list item) 元素沒有結(jié)束標(biāo)簽。但是由于元素的結(jié)束和另一個的開始很容易推斷出來,因此上圖中并沒有太嚴(yán)重的渲染錯誤。
2.第一個 <strong> 元素沒有結(jié)束標(biāo)簽。這就嚴(yán)重了,因為該元素結(jié)束的位置難以確定。事實上所有剩余文本都加粗了。
3.一下嵌套有問題:<strong>重點(strong)<em>重點強(qiáng)調(diào)(strongly emphasised)?</strong>這又是什么鬼?</em>????。瀏覽器很難做出正確解釋,理由同上。
4.href 屬性缺少了一個雙引號。從而導(dǎo)致了一個最嚴(yán)重的問題:整個鏈接完全沒有渲染出來。
```
* 下面暫時忽略源代碼中的標(biāo)記,先看一下瀏覽器渲染出的標(biāo)記。打開瀏覽器的開發(fā)者工具。如果不太熟悉,請先閱讀 瀏覽器開發(fā)工具概覽。
* 在 DOM 查看器中可以看到渲染的標(biāo)記:
![圖片描述](/upload/attach/202011/202011301706_HA7U5MCSKEPEM92.png)
* 通過 DOM 查看器可以清楚地看到,瀏覽器已經(jīng)嘗試修補(bǔ)代碼錯誤(我們嘗試了 Firefox,其他現(xiàn)代瀏覽器也應(yīng)給出同樣結(jié)果):
段落和列表元素加上了關(guān)閉標(biāo)簽
第一個 <strong> 沒有明確的關(guān)閉標(biāo)簽,因此瀏覽器為之后所有獨立塊都補(bǔ)全了 <strong></strong>。
瀏覽器是這樣修補(bǔ)嵌套錯誤的:
```
<strong>重點(strong)
<em>重點強(qiáng)調(diào)(strongly emphasised)?</em>
</strong>
<em>這又是什么鬼?</em>
```
刪除整個缺少雙引號的鏈接。最后一個列表項就成了:
```
<li>
<strong>未閉合的屬性:另一種 HTML 常見錯誤。來看一個示例:</strong>
</li>
```
# HTML 驗證
閱讀以上示例后,你發(fā)現(xiàn)保持良好 HTML 格式的重要性。那么應(yīng)該如何做呢?以上示例規(guī)模較小,查找錯誤還不難,但是一個非常龐大、復(fù)雜的 HTML 文檔呢?
最好的方法就是讓你的HTML頁面通過 Markup Validation Service。由 W3C(制定 HTML、CSS 和其他網(wǎng)絡(luò)技術(shù)標(biāo)準(zhǔn)的組織) 創(chuàng)立并維護(hù)的標(biāo)記驗證服務(wù)。把一個 HTML 文檔加載至本網(wǎng)頁并運(yùn)行 ,網(wǎng)頁會返回一個錯誤報告。
![圖片描述](/upload/attach/202011/202011301708_7D5Y6K6UVEA2B56.png)
網(wǎng)頁可以接受網(wǎng)址、上傳一個 HTML 文檔,或者直接輸入一些 HTML 代碼。