2009-01-16 62 views
1

當我的XHTML頁面出現標記錯誤時,Mozilla Firefox顯示「黃色死亡屏幕」,在黃色背景上只顯示大量紅色錯誤消息。我可以使用Javascript檢測XHTML解析錯誤嗎?

儘管這些錯誤很罕見,但它們是非常不利於用戶不友好的

有沒有一種方法可以檢測這些使用Javascript,從而發送消息回服務器?

到目前爲止我發現的: - 解析錯誤仍然運行之前放置的腳本。 (當然。) - 在這些腳本中設置的超時和時間間隔仍將在解析錯誤後執行。 - 在Firefox中,DOM是<parsererror>,其中包含<sourcetext>。如果我查詢document.firstChild.tagName,我可以檢測到這一點。

剩餘問題: - 我可以偵聽哪些事件來檢測這種情況? (輪詢很糟糕。) - 如何在其他瀏覽器中檢測到此情況?

回答

2

在客戶端捕獲解析錯誤可能是可能的,但它確實解決了錯誤的問題。

我知道這不是你所要求的,但是除非你真的像XHTML一樣做了一些特定的內容,比如嵌入一些其他標記語言,否則你應該把你的頁面作爲text/html而不是application/xhtml + xml。即使它是XHTML。通過將其作爲text/html提供,您將避免您遇到的問題,並讓您的頁面在IE中也能正常工作。請注意,它是MIME類型,而不是確定使用哪個分析器的doctype聲明 - 使用過渡型文檔不會。這就是說,如果你確定你希望你的頁面被解析爲XHTML,最好在服務器上處理這種錯誤。通過構建DOM生成頁面,然後發送序列化結果。如果這不是一個選項,那麼首先按照現在的方式生成頁面,但不要將其傳輸到客戶端。以生成的XHTML爲例,使用驗證的XHTML解析器(或者至少是通用的XML解析器)解析服務器端。如果您遇到錯誤,請顯示您想要的任何錯誤頁面。否則,序列化解析的DOM並將其發送給客戶端。

總之,使用應用程序/ xhtml + xml的基本規則是:

  1. 不要。
  2. (對於高級用戶)不要,除非你已經證明你正在做的事情,如果頁面被作爲文本/ HTML提供不起作用。這適用於XHTMl文檔百分比很小的一小部分。
  3. 如果您必須將您的頁面作爲application/xhtml + xml進行處理,請使用一些保證有效性的方法生成它。
  4. 除非你真的知道你在做什麼,從來沒有使用application/xhtml + xml作爲包含用戶輸入的頁面。

請記住,XHTML只是HTML 4的重新配置以及嵌入其他語言的能力。如果你不使用嵌入,你有什麼是具有不同但幾乎完全兼容的語法的HTML 4。絕大多數XHTML文檔都是以text/html的形式提供的,因此被瀏覽器視爲HTML 4。

+0

+1,除了用戶輸入在XHTML中並不比普通的舊HTML更危險;如果攻擊者可以潛入一個 bobince 2009-01-16 11:39:44

0

我知道這可能不是最有用的答案,但您是否考慮切換到過渡文檔類型?

通過一切手段,通過解析器來檢測您的文件,以檢測錯誤,但脫機 - 它顯示用戶YSOD的風險是不值得的!

+0

過渡/嚴格是不倫不類的,他們都將無法解析,如果您的服務器不構成井內容爲XML。但是,是的,在打擊用戶之前檢查格式良好是一種方式。 – bobince 2009-01-16 11:36:51

1

這並不回答你的問題,但是,相反,爲什麼不在你的服務器上驗證你的XHTML,生成它之後,還是在你發送給瀏覽器之前?

1

我的第一個問題是:由於Internet Explorer不容易讓你真正指定application/xhtml + xml作爲MIME類型,也不支持這一切,爲什麼你需要檢測XHTML解析錯誤?

作爲檢測錯誤 - 看看http://www.quirksmode.org

1

我建議你驗證服務器端的文件。但是,如果你真的想在客戶端做到這一點,如果正確地進行輪詢(這意味着輪詢被保證終止),輪詢沒有任何問題。

在以下應該工作至少Firefox和Opera:

(function() { 
    if(document.documentElement && 
     document.documentElement.getAttribute('xmlns') !== 
     'http://www.w3.org/1999/xhtml') { 
     alert('parsing errors'); 
    } 
    else if(document.body && document.body.lastChild) { 
     alert('no parsing errors'); 
    } 
    else setTimeout(arguments.callee, 100); 
})(); 
相關問題