王雪峰,陳興穌
(伊犁師范大學(xué) 網(wǎng)絡(luò)安全與信息技術(shù)學(xué)院,新疆 伊寧 835000)
現(xiàn)如今,電子商務(wù)的發(fā)展使人們對網(wǎng)上辦公和辦事的需求越來越高。人們對網(wǎng)站的需求促進(jìn)了網(wǎng)站的層出不窮,并且逐漸呈現(xiàn)多元化的態(tài)勢。瀏覽器的種類隨著需求增多也變得多樣化,而不同的瀏覽器有不同的內(nèi)核,這就導(dǎo)致相同網(wǎng)頁在不同瀏覽器顯示的效果不同,有些甚至大相徑庭,如版面顯示不正常、部分功能顯示不全等。對于網(wǎng)站的設(shè)計(jì)者和開發(fā)者來說,最為首要也是最難的任務(wù)之一就是解決瀏覽器兼容性,以保證同一網(wǎng)站在每一個(gè)瀏覽器前臺中打開后所呈現(xiàn)的網(wǎng)站內(nèi)容都是一致的,這也成為網(wǎng)站建設(shè)方面經(jīng)久不衰的課題。本文首先從現(xiàn)階段常見的火狐、Chrome、百度、360 等瀏覽器入手,介紹各個(gè)瀏覽器內(nèi)核情況、分析其瀏覽器的不兼容問題,接著主要探討瀏覽器的渲染相關(guān)兼容性和腳本兼容問題[1-2],并對發(fā)生的不兼容問題的原因進(jìn)行分類和具體分析,最后有針對性地提出了解決瀏覽器不兼容問題的方法。
瀏覽器全稱網(wǎng)頁瀏覽器,是用于檢索并展示萬維網(wǎng)信息資源的軟件應(yīng)用程序。用戶可以通過瀏覽器連接網(wǎng)絡(luò),通過網(wǎng)絡(luò)地址確定信息資源位置、訪問網(wǎng)絡(luò)上的信息資源,解析到網(wǎng)絡(luò)頁面上,并提取出來。信息資源可為網(wǎng)頁、音頻、視頻、圖片、文字以及其他可見信息[3]。
瀏覽器可以分為瀏覽器外殼、內(nèi)核兩部分[4],其中提供操作界面、參數(shù)設(shè)置的外殼種類繁多因此重要程度低,內(nèi)核部分才是瀏覽器的核心。用來標(biāo)記語言、顯示內(nèi)容的程序模塊內(nèi)核主要分為渲染引擎和JavaScript腳本引擎兩部分,瀏覽器內(nèi)核用來識別網(wǎng)頁中HTML、XML、圖像等內(nèi)容,通過程序模塊整理網(wǎng)頁中加入的CSS 等信息,在顯示器上把網(wǎng)頁呈現(xiàn)出來。不同的瀏覽器內(nèi)核解析同一個(gè)網(wǎng)頁語法時(shí)會(huì)出現(xiàn)不同的渲染效果,所以用戶選擇不同瀏覽器查看同一網(wǎng)頁時(shí)會(huì)出現(xiàn)兼容性問題。
目前,市場上常見和常用的瀏覽器內(nèi)核可以分為Trident,Gecko,Blink,Webkit4 種。
(1)Trident:又稱MSHTML,是IE 瀏覽器一直使用的內(nèi)核。微軟公司在Mosaic 代碼的基礎(chǔ)上修改而來并在IE 瀏覽器中沿用至今,因?yàn)閮?nèi)核的開放性,曾脫離了W3C 標(biāo)準(zhǔn),而且內(nèi)核有漏洞,導(dǎo)致了安全性低,并且不是開源的,只適用于Windows 平臺,存在很多兼容性問題。國內(nèi)獵豹瀏覽器、百度瀏覽器、360 極速瀏覽器都使用了該內(nèi)核。
(2)Gecko:即Mozilla Firefox 內(nèi)核,最大的優(yōu)勢是開源和跨平臺,在Windows,Linux,Macos X 等操作系統(tǒng)中都能運(yùn)行,代表作是火狐瀏覽器。
(3)WebKit 內(nèi)核:由KHTML(Kool Desktop Environment)系統(tǒng)開發(fā)的HTML 網(wǎng)頁排版引擎之一發(fā)展而來,是蘋果公司自主研發(fā)的內(nèi)核,也是Safari 瀏覽器使用的內(nèi)核。此內(nèi)核具有高速、遵循W3C 標(biāo)準(zhǔn)的特點(diǎn)。蘋果產(chǎn)品中常見的瀏覽器都是采用WebKit 內(nèi)核。Google Chrome,Opera 及各種國產(chǎn)瀏覽器高速模式也使用Webkit 作為內(nèi)核。
(4)Blink 內(nèi)核:是由Google 和Opera software 于2013 聯(lián)合開發(fā)的排版引擎。現(xiàn)在依然活躍的Chrome瀏覽器的內(nèi)核是Blink,谷歌還開發(fā)了自己的JS 引擎即V8,它能夠極大地提高JS 的運(yùn)行速度。
本文所說的瀏覽器出現(xiàn)的兼容性問題,是因?yàn)闉g覽器采用的瀏覽器內(nèi)核不同。而不同的內(nèi)核解析同一個(gè)網(wǎng)頁的代碼時(shí)會(huì)出現(xiàn)不同的渲染效果,這就造成了顯示屏上網(wǎng)頁頁面顯示不相同。例如:字高度不受控制、字間距不受控制、圖片間距不受控制、圖片透明性的問題等眾多兼容性問題。研究瀏覽器兼容性問題的最終目的在于:無論用戶用什么瀏覽器來訪問網(wǎng)站或者登錄系統(tǒng)時(shí),都應(yīng)該得到統(tǒng)一的檢索效果。
不同的瀏覽器所使用的內(nèi)核及支持的HTML,XML等網(wǎng)頁語言的標(biāo)準(zhǔn)不同,因此不同的瀏覽器內(nèi)核能支持的網(wǎng)頁編寫的解釋也不同。這會(huì)導(dǎo)致同一網(wǎng)頁在不同瀏覽器上顯示效果頁面布局效果不一樣,這是造成瀏覽器兼容性問題的主要原因[5]?,F(xiàn)今常見的瀏覽器的渲染引擎(又稱排版引擎)和腳本引擎如表1 所示。
表1 瀏覽器渲染引擎和腳本引擎
渲染相關(guān)的兼容性問題又稱樣式相關(guān)的問題,發(fā)生的兼容性問題都體現(xiàn)在頁面布局效果上[6]。在CSS,HTML 渲染相關(guān)的問題主要為字高度、間距、居中等問題。例如網(wǎng)頁代碼中運(yùn)用了 text-align :center 將網(wǎng)頁設(shè)置成水平居中,IE6,IE7 瀏覽器的訪問下確實(shí)達(dá)到了按照設(shè)置顯示的效果,但同樣的網(wǎng)頁代碼,在IE8或者火狐瀏覽器下顯示的文本有居中,可其他嵌套塊元素并未居中。網(wǎng)頁出現(xiàn)字高度、間距、居中等不兼容問題都是因?yàn)閃eb 的排版標(biāo)準(zhǔn)CSS 不同,目前的CSS已經(jīng)有數(shù)多版本。
如果瀏覽器的內(nèi)核不一樣,瀏覽器對標(biāo)簽的解釋會(huì)有自己的規(guī)則,不同瀏覽器對CSS 的支持、解析加載都不一樣,導(dǎo)致不同瀏覽器頁面顯示效果不一致。為了使同一頁面在不同瀏覽器上呈現(xiàn)一致的效果、消除瀏覽器解析差異,本文選用CCS hack 方式來使CCS 兼容不同的瀏覽器。
(1)塊級元素設(shè)置問題描述:塊級元素同時(shí)設(shè)置了float 和橫向的margin 屬性后,橫向外邊距比設(shè)置的值大,會(huì)出現(xiàn)原先內(nèi)容放不下而擠到下一行的現(xiàn)象,設(shè)置float 布局是最常見的瀏覽器兼容問題。
解決方案:因?yàn)閒loat 和橫向的margin 屬性同時(shí)設(shè)置后,橫向間距在不同內(nèi)核解析是不一樣的,所以就出現(xiàn)了基本上每個(gè)瀏覽網(wǎng)頁的用戶都遇到過的兼容性問題。用戶只需在網(wǎng)頁代碼中設(shè)置float 標(biāo)簽樣式控制時(shí),添加一行display:inline;代碼,將原先的內(nèi)容都轉(zhuǎn)化為行內(nèi)元素,這樣就不會(huì)出現(xiàn)因?yàn)闄M向間距不同而造成顯示效果不同的情況。
(2) 行內(nèi)屬性標(biāo)簽設(shè)置問題描述:設(shè)置屬性display:block 后采用浮動(dòng)float 布局,又有橫向間距的margin 的情況下,IE6 顯示網(wǎng)頁文本字體出現(xiàn)間距不一致的bug。運(yùn)行后出現(xiàn)IE6 里的間距超過設(shè)置的float布局間距的現(xiàn)象。
解決方案:在原有設(shè)置屬性display:block;的代碼后面添加上 display:inline;display:table;代碼。解決上面的兼容性問題提到塊級元素設(shè)置時(shí),加上display:inline 的話,本身的行內(nèi)標(biāo)簽轉(zhuǎn)變成行內(nèi)元素,此時(shí)高寬就不可設(shè)置了。這時(shí)候用戶還需要在display:inline后面加入display:table 代碼,這樣既可以顯示為行內(nèi)元素,又可以設(shè)置高和寬。
(3)網(wǎng)頁版面中無法定義1px 左右高度的、使用率低而被忽略的容器,在IE6 下這個(gè)問題是因?yàn)槟J(rèn)的行高造成的。
解決方案:代碼部分加入overflow:hidden,zoom:0.08,line-height:1px 等語句的其中之一就可以得到解決。
(4)form 標(biāo)簽、ul 標(biāo)簽等在IE 中,將會(huì)自動(dòng)設(shè)置margin 的邊距,而在Firefox 中margin 邊距值則是0。
解決方案:如果想顯示一致,在原有的設(shè)置屬性上,CSS 中指定margin 和 padding 屬性,CSS 中一般先設(shè)置全局屬性 *{margin:0;padding:0;},先將標(biāo)簽的不同邊距都設(shè)置為0 或者其他的固定值。
由于各類型瀏覽器內(nèi)核不同,在前端網(wǎng)站設(shè)計(jì)中所使用的腳本代碼不同,對所發(fā)生的事件也有不同的處理方式。因此對同一段腳本文字命令解析不同會(huì)出現(xiàn)頁面顯示效果不統(tǒng)一或者腳本執(zhí)行錯(cuò)誤的情況、客戶端檢索過程中網(wǎng)頁的部分區(qū)域出現(xiàn)亂碼[7-8]。
解釋腳本兼容性問題,使用者要把同一腳本文件放在不同的瀏覽器中運(yùn)行。例如以下幾個(gè)簡單的例子可以說明:
(1)在IE 系列中,event 對象有 x,y 屬性,FxExplorer(以下簡稱“Fx”)瀏覽器中則沒有;
(2)在IE 系列中可以用window.testFrame 取得該frame,Fx 瀏覽器中不行;
(3)在IE 系列中不能使用const 鍵字。如 const constVar=32;代碼在IE 瀏覽器中運(yùn)行就是語法錯(cuò)誤;
(4)在Fx 瀏覽器中,所有節(jié)點(diǎn)均有 nodeName 值,但 textNode 沒有 tagName 值。在 IE 中,nodeName 就沒有問題。
瀏覽器的腳本兼容性一直是開發(fā)者和使用者特別注重的問題。不同瀏覽器對同一段代碼的不同解析導(dǎo)致瀏覽器不兼容,解決腳本兼容性問題還要考慮到不同瀏覽器的不同cookie 鑰匙。主流的瀏覽器如IE,Chrome,Opera 的cookie 是可以保存Unicode(統(tǒng)一碼)字符;火狐瀏覽器(Firefox)則是先保存中文字符內(nèi)碼,而后在檢索空閑時(shí)將它轉(zhuǎn)換為Unicode 字符來存儲;Safari 瀏覽器會(huì)忽略包含中文字符的鍵值對。瀏覽器在設(shè)置和讀取cookie 時(shí),對字符進(jìn)行編、解碼操作時(shí)把字符串編碼為 URI 組件,推薦使用encodeURIComponent()對字符進(jìn)行編碼和使用decodeURIComponent()對編碼后的字符進(jìn)行解碼,有以下幾種情況。
(1)瀏覽器中如IE,Firefox,Opera 在自定義提交方式下不會(huì)提交普通按鈕及提交按鈕的鍵值對信息;而Safari,Chrome 瀏覽器會(huì)將這些信息也提交給服務(wù)器端。
解決辦法:通常情況下,服務(wù)器端不需要按鈕的key/value 信息,HTML 網(wǎng)頁中的提交按鈕(submit)在提交之前會(huì)被瀏覽器定義了name 值,服務(wù)器上一樣可以得到它的 name 值和value 值,建議刪除按鈕的name屬性,使其無法成為有效的表單元素,服務(wù)器上就得不到name 和value 值,從而不能提交submit 的name屬性值。
(2)Content-Type 用于指示資源的MIME 類型,后面往往跟著字符串或者文檔文件,代表著服務(wù)器端發(fā)送給客戶端瀏覽器的具體數(shù)據(jù)類型,瀏覽器將根據(jù)這個(gè)信息決定如何處理得到的數(shù)據(jù)內(nèi)容,如:Contenttype:text/html 表示這是個(gè)HTML 文件,需要渲染引擎解釋內(nèi)容后輸出;Content-type:application/octet-stream表示這是個(gè)二進(jìn)制流,需要下載到本地后由用戶端環(huán)境決定如何使用。
每個(gè)瀏覽器內(nèi)置支持的Content-type 類型表各不相同,這導(dǎo)致了某些類型字符串在某些瀏覽器下不被識別;另外,如果出現(xiàn)錯(cuò)誤的Content-type 類型,各個(gè)瀏覽器又會(huì)以不同的方式處理。
解決辦法:這個(gè)問題比較復(fù)雜,如需避免出現(xiàn)顯示異常的情況,建議不要使用非法的Content-Type 頭字符串;并且文件實(shí)際內(nèi)容和數(shù)據(jù)格式應(yīng)與Content-type 頭字符串內(nèi)類型聲明一致。
(3)在瀏覽器IE6,IE7,IE8 中,若一個(gè)頁面被打開時(shí)接收到的響應(yīng)頭的Content-type 為text/plain,瀏覽器會(huì)嘗試嗅探頁面文件內(nèi)實(shí)際內(nèi)容來判斷是否可能為一個(gè)HTML 文檔,若是則會(huì)以text/html 的方式將頁面作為HTML 文檔解釋,而不是將其作為純文本內(nèi)容處理。
解決辦法:這是由IE 瀏覽器的特有內(nèi)容嗅探機(jī)制導(dǎo)致的,故在不修改服務(wù)器端代碼的情況下,無法通過常規(guī)辦法解決此IE 特性問題。合理、正確地設(shè)置文檔的Content-type 是最佳的解決方案,同時(shí)應(yīng)避免在非HTML 文件中出現(xiàn)可被IE6,IE7,IE8 嗅探機(jī)制捕獲的HTML,BODY,HEAD,TITLE 標(biāo)記書寫格式。
(4)IE6 瀏覽器不支持Really Simple Syndication(RSS),RSS 是同步網(wǎng)站內(nèi)容的一種標(biāo)準(zhǔn),使用瀏覽器打開響應(yīng)頭為application/rss+xml 的內(nèi)容會(huì)當(dāng)做二進(jìn)制文件而提示下載;Chrome 瀏覽器會(huì)將application/rss+xml 以純文本處理而顯示出源代碼。
解決辦法:各瀏覽器對于RSS 的支持及渲染方式為瀏覽器各自實(shí)現(xiàn),故無法通過常規(guī)辦法使各瀏覽器達(dá)到一致的效果,對于暫不支持RSS 的瀏覽器應(yīng)給予提示。Chrome 瀏覽器可通過安裝擴(kuò)展插件實(shí)現(xiàn)此功能。
(5)瀏覽器IE6,IE7,IE8 這3 個(gè)版本在調(diào)整的過程中,始終不在使用META 元素控制跳轉(zhuǎn)時(shí)附加Referer(HTTP 請求Header 的一部分)字段到請求頭中。在普通頁面中,當(dāng)腳本調(diào)用location 對象進(jìn)行跳轉(zhuǎn)時(shí)也不會(huì)附加Referer 字段信息。
解決辦法:若服務(wù)端需要獲得正確的Referer 字段信息,則應(yīng)采用各瀏覽器均可以附加Referer 字段信息的方式進(jìn)行跳轉(zhuǎn)。例如普通超鏈接、表單提交、HTTP 302 跳轉(zhuǎn)等。
本文主要針對不同的瀏覽器內(nèi)核,主要有4 類Trident,Gecko,Blink,Webkit,對現(xiàn)有常用的瀏覽器IE、火狐、Chrome 的渲染引擎和腳本引擎進(jìn)行分析;針對渲染引擎造成的兼容性問題,主要分析了4 種情況下的CSS 設(shè)置版面布局問題,并給出了解決方法;針對腳本引擎造成的問題,主要分析了5 種主要情況,并給出了相應(yīng)的解決方法。通過瀏覽器的渲染兼容性和腳本兼容性的分析,給出了Web 前端網(wǎng)站設(shè)計(jì)應(yīng)該解決的版面布局問題,解決了同一個(gè)網(wǎng)站在不同瀏覽器中顯示效果不一致的問題。