王乾坤*
(無錫城市職業(yè)技術(shù)學院語言創(chuàng)意系,江蘇無錫,214001)
基于BS架構(gòu)的優(yōu)勢是顯而易見,不僅升級更方便而且對客戶端要求低??蛻糁恍枰幸豢詈线m的瀏覽器即可運行系統(tǒng)。作為管理系統(tǒng)而言與普通網(wǎng)站在設(shè)計時存在很大的區(qū)別,普通網(wǎng)站的信息多是單向的,客戶主要是從網(wǎng)站上瀏覽數(shù)據(jù)。而管理系統(tǒng)更傾于與客戶的交互,客戶不僅要從服務(wù)器上獲取信息,還需要向服務(wù)器提交信息。所以在基于BS架構(gòu)的管理系統(tǒng)設(shè)計時,遇到的問題更改設(shè)計要求更高。主要問題集中在瀏覽器兼容性、提交或顯示中文時亂碼以及如何實現(xiàn)前端代碼的復(fù)用性。從以上幾方面,筆者從實際設(shè)計經(jīng)驗出發(fā)進行了分析和總結(jié)。
當前瀏覽器市場百家爭鳴,不同產(chǎn)品以及各種版本層出不窮。每款瀏覽器為吸引不同客戶群體,設(shè)計傾向特性不同。比如360瀏覽器等面向以瀏覽信息為主的客戶,所以提高瀏覽網(wǎng)頁速度,乃至于不惜犧牲部分交互功能(默認關(guān)閉JS功能)。作為基于BS架構(gòu)的管理系統(tǒng)而言,JS的使用是必不可少的。另外,實現(xiàn)同一功能的JS代碼對不同瀏覽器而言,雖大同而有小異。就這么一點點小異,如果設(shè)計不當,小則影響網(wǎng)頁效果大則導致設(shè)計功能無法實現(xiàn)。
(1)打開第一扇門:先讓 JS運行起來。筆者的做法是在登錄頁即進行偵測是否禁用 JS,如禁用則提示用戶必須打開 JS。具體代碼是:。
(2)對象獲取問題:FireFox獲取對象的方法是document.getElementById(“idName”);而 IE 方法是 document.idname 或者 document.getElementById(“idName”)。統(tǒng)一方法:document.getElementById(“idName”);
(3)const問題:Firefox可以使用const關(guān)鍵字或var關(guān)鍵字來定義常量;IE只能使用var關(guān)鍵字來定義常量。統(tǒng)一方法使用var。
(4)event.x與 event.y問題:IE的 event對象有 x,y屬性,但是沒有pageX,pageY屬性;Firefox下,event對象有pageX,pageY屬性,但是沒有x,y屬性。解決方法:使用mX(mX=event.x?event.x:event.pageX;)來代替IE下的event.x或者Firefox下的event.pageX。
(5)window.location.href問題:IE下可以使用window.location或window.location.href;Firefox能使用window.location。解決方法:使用window.location
(6)frame問題:訪問frame對象時IE使用window.frameId或者window.frameName來訪問這個frame對象.frameId和frameName可以同名。Firefox只能使用window.frameName來訪問這個frame對象。另外,在IE和Firefox中都可以使用 window.document.getElementById(“frameId”)來訪問這個 frame對象。
(7)模態(tài)和非模態(tài)窗口問題:IE可以通過 showModalDialog和 show ModelessDialog打開模態(tài)和非模態(tài)窗口;Firefox則不能。解決方法:直接使用window.open(pageURL,name,parameters)方式打開新窗口。
(8)firefox與IE的父元素(parentElement)的區(qū)別:IE:obj.parentElement;firefox:obj.parentNode。解決方法:因為firefox與IE都支持DOM,因此統(tǒng)一使用obj.parentNode。
(9)document.formName.item(“itemName”)問題:IE 使用 document.form Name.item(“itemName”) 或 document.formName.elements[“elementName”] ;Firefox只能使用 document.formName.elements[“elementName”]。解決方法:使用 document.formName.elements[“elementName”]。
(10)集合類對象問題:IE可以使用()或[]獲取集合類對象;Firefox只能使用[]獲取集合類對象。解決方法:統(tǒng)一使用[]獲取集合類對象。
(11)自定義屬性問題:IE可以使用獲取常規(guī)屬性的方法來獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性;Firefox只能使用getAttribute()獲取自定義屬性。解決方法:統(tǒng)一通過getAttribute()獲取自定義屬性。
以上列述了功能問題以及解決方法,另外還有一些外觀以及式樣問題,如Table操作問題、對象寬高賦值問題、CSS透明等等。這里不在贅述。
在項目中經(jīng)常會遇到中文傳參數(shù),在后臺接收到亂碼問題。那么在遇到這種情況下我們應(yīng)該怎么進行處理讓我們傳到后臺接收到的參數(shù)不是亂碼是我們想要接收的到的,下面就是一些認識和理解。
(1)get請求url中帶有中文參數(shù),有三種方式進行處理防止中文亂碼:
1)如果使用tomcat作為服務(wù)器,那么修改tomcat配置文件conf/server.xml中,在 2)前臺需要對中文參數(shù)進行編碼,調(diào)用js方法encodeURI(url),將url編碼,然后請求。后臺接受時,需處理Stringstr=newString(request.getParameter("param").getBytes("iso8859-1"),"UTF-8"); 原因:tomcat不設(shè)置編碼時,默認是 iso8859-1,即 tomcat默認會以iso8859-1編碼接收get參數(shù)。以上操作是將參數(shù)以iso8859-1編碼轉(zhuǎn)化為字節(jié)數(shù)組,然后再以UTF-8將字節(jié)數(shù)組轉(zhuǎn)化為字符串。 (2)解決get請求,后臺接受中文參數(shù)亂碼處理的方法(搜索功能帶參數(shù)) 1)前臺獲取數(shù)據(jù),在js中進行編碼處理encodeURI函數(shù)采用utf-8進行編碼,而在服務(wù)器的進行解碼時候,默認都不是以uft-8進行解碼,所以就會出現(xiàn)亂碼。兩次encodeURI,第一次編碼得到的是UTF-8形式的URL,第二次編碼得到的依然是UTF-8形式的URL,但是在效果上相當于首先進行了一次UTF-8編碼(此時已經(jīng)全部轉(zhuǎn)換為ASCII字符),再進行了一次iso-8859-1編碼,因為對英文字符來說UTF-8編碼和ISO-8859-1編碼的效果相同。 2)后臺解碼處理 在后臺接收參數(shù)時候,首先通過request.getParameter()自動進行第一次解碼(可能是gb2312,gbk,utf-8,iso-8859-1等字符集,對結(jié)果無影響)得到ascii字符,然后再使用UTF-8進行第二次解碼,通常使用java.net.URLDecoder("","UTF-8")方法。 兩次編碼兩次解碼的過程為:UTF-8編碼->UTF-8(iso-8859-1)編碼->iso-8859-1解碼->UTF-8解碼,編碼和解碼的過程是對稱的,所以不會出現(xiàn)亂碼。 (3)前后臺參數(shù)轉(zhuǎn)譯的方法 如果以上兩種方法都解決不了問題,那么就是參數(shù)轉(zhuǎn)譯的方法。其原理是:參數(shù)傳遞里用英文或數(shù)字標識。在接收到以后根據(jù)英文或數(shù)字標識再轉(zhuǎn)譯成中文。這種方法對規(guī)范化的參數(shù)是可行的。但會增加代碼量。另外,對非規(guī)范化的文本參數(shù)而言,這種方法尚不適用。 (1)前端開發(fā)過程中,以下幾個問題尤為突出: 1)前端代碼的復(fù)用性差。大多是復(fù)制粘貼似的復(fù)用 2)前端代碼可維護性差。沒有統(tǒng)一的規(guī)范和標準,一個人一個風格,即使有的開發(fā)團隊有這個意識要規(guī)范,實施起來也很困難。 3)可讀性不強。因為和后端到處是交互。而且有時候邊界很模糊,比如:通常我們遵循mvc的思想進行開發(fā),但是,前端有時候,也存在數(shù)據(jù)的處理。Js的DOM操作,或者對Json數(shù)據(jù)的再次處理。顯得有重復(fù)。 4)大部分中小型的公司,可能由于技術(shù)或者資金等其他客觀原因,使得開發(fā)過程根據(jù)就不分離前端后端。這就導致了開發(fā)效率的降低,質(zhì)量的降低。付出的代價就是復(fù)用性、可維護性差。 5)國內(nèi)目前大多數(shù)的前端開發(fā)人員,水平不是很高,而且參差不齊。但是需求量越來越大。因為前端,入門的門檻較低,導致這樣的問題比較嚴重。一般,技術(shù)問題很少,有,也就是兼容性的問題了。更多的是:工程類的問題。規(guī)范和效率、質(zhì)量上的矛盾比較尖銳。 (2)如何解決前端復(fù)用呢?筆者認為可以有以下兩個思路: 1)盡可能原生,并構(gòu)建本公司的UI庫 原生js,html搭建的網(wǎng)頁是蠻難維護的,比如一個表單驗證,一大堆if else肯定以后維護或者添加功能上面就麻煩很多。 原生的復(fù)用也就是代碼復(fù)用,把代碼功能抽象出來,表單驗證的功能都類似吧?把功能抽象到方法,比如驗證字符串的個數(shù),compare,密碼是不是相等,郵箱,手機的驗證,正則表達式的驗證。 傳參驗證。每次我只需要定義驗證規(guī)則和傳入input的值就可以。這樣一個驗證的類,我就把今生所需要寫的所有表單驗證的邏輯寫完了。 項目有兩個頁面需要驗證,不要寫2遍if else,調(diào)用這個類,傳相應(yīng)參數(shù)。拓展類,拓展規(guī)則。這樣你原來的代碼不用改,不需要知道以前一堆jq是什么含義,只需要拓展這個類就可以了。一種好的代碼規(guī)范就是拓展而不是修改。 2)適度借助力框架 如angular好的實踐就是在controller里面不要加太多業(yè)務(wù)邏輯和dom操作。如果我們想復(fù)用就別讓它依賴當前controller。angular的指令分裝飾型指令和組件。一般復(fù)用就要組件不依賴外部環(huán)境,這樣你才能把這個指令用到任何地方。我們把該指令分離,他需要的數(shù)據(jù)通過屬性傳進去,類似 vue和react的props。另外像react就提倡的web components,它的每個部分都是一個組件,當然數(shù)據(jù)是props傳入的,他都給想好了。這個組件就比較好復(fù)用了,它維護自身的state,一個組件一個state,兩個組件基本上沒有任何的耦合。那么復(fù)用就好做多了。組件的通信就通過props,子與父組件的通信就需要全局的事件系統(tǒng)了。react復(fù)用是做的很好了,但是它沒有雙向綁定,驗證表單寫起來較麻煩一點,組件間的通信也很麻煩。所以寫react應(yīng)用的時候,子組件一般就充當渲染組件,上面?zhèn)魇裁磪?shù)我渲染什么,而且react組件不要嵌套太深,好的實踐是扁平化,如果用了redux,就會發(fā)現(xiàn)如果嵌套太多組件,state是很難維護的。 從客戶體驗角度來說。使用的系統(tǒng)應(yīng)該穩(wěn)定、簡單??蛻糁恍枰P(guān)心自身的業(yè)務(wù)即可。所以BS解決了系統(tǒng)安裝與升級的困擾。但BS系統(tǒng)的不穩(wěn)定性和不方便性特點是未來致力與BS架構(gòu)發(fā)展的開發(fā)設(shè)計人員,仍需要努力的方向。 [1] 廖旭. 基于 BS架構(gòu)的 SAP開發(fā)技術(shù)研究[J]. 中國戰(zhàn)略新興產(chǎn)業(yè),2017,(20). [2] 許建強. 基于BS架構(gòu)的檔案登記備份軟件優(yōu)劣解析與結(jié)構(gòu)優(yōu)化[J].浙江檔案, 2014(09). [3] 王成,李少元,鄭黎曉,等.Web前端性能優(yōu)化方案與實踐[J]. 計算機應(yīng)用與軟件, 2014,(12). [4] 趙經(jīng)緯,周余,王自強, 等.基于 Webkit的嵌入式瀏覽器的研究與實現(xiàn)[J].電子測量技術(shù), 2009, (03). [5] 李穎,陳敏.瀏覽器不正當競爭案件調(diào)查報告[J].競爭政策研究,2015,(01).3 前端代碼的復(fù)用性
4 結(jié)束語