文章出處

  上篇里我講到了一種前后端分離方案,這套方案放到服務端開發人員面前比放在web前端開發人員面前或許得到的掌聲會更多,我想很多資深前端工程師看到這樣的技術方案可能會有種說不出來的矛盾心情,當我的工作逐漸走向越來越專業化的前端開發后,我就時常被這套前后端分離方案所困惑,最近我終于明白了這個困惑的本源在哪里了,那就是這套前后端分離方案其實是服務端驅動的前后端分離方案,它的實現手段又是從服務端的MVC架構體系演化而來,因此該方案最大的問題就是它并沒有從根本上改變web前端從屬于服務端的被動局面。那么問題來了,有沒有以web前端為驅動的前后端分離方案呢,該方案能讓web前端的能力獲得更大的釋放了?答案是絕對有。本篇就要講講以web前端驅動的前后端分離方案

  首先要提的就是javascriptMVC,下面我摘抄的是維基百科里對javascriptMVC的解釋,具體如下:

  首先是簡介:

JavaScriptMVC 是一套開放源代碼的多樣化互聯網應用程序框架,以 jQuery 與 OpenAJAX 為基礎。JavaScriptMVC 利用 MVC 架構與工具擴展這些函式庫,以便開發與測試。由于 JavaScriptMVC 不需要任何服務器端的配合,因此它可以和任何的網站服務接口與編程語言整合,如 ASP.NET、Java、Perl、PHP、Python 或 Ruby。

 

  接下來是歷史:

JavaScriptMVC 的第一個版本是在2008年5月釋出。穩定版的 JavaScriptMVC 2.0 在2009年6月釋出,并以 jQuery 為基礎。主要開發目標為維持程式碼的簡短和專注在它獨特的功能上。3.0版本在2010年12月釋出。而從 JavaScriptMVC 中所獨立出來的 MVC 架構“CanJS”則在2012年4月釋出。

  從維基百科里的解釋我們會發現如下啟示,它們分別如下:

  啟示一:javascriptMVC是一個應用框架的名字,這和jQuery的命名是一樣的,所以這里我要聲明一下,本系列里的javascriptMVC不是指代這個框架,而是指代的是使用javascript語言實現出的一類的web前端的MVC框架,本系列后面的javascriptMVC和前端MVC的含義是一致的。

  啟示二:從javascriptMVC歷史里我們可以看到第一版的javascriptMVC產生于2008年,這個歷史要遠早于nodejs出現的時間,這說明了前端的MVC并不是因為nodejs的出現而產生的,應該是nodejs推動了前端的MVC框架的應用和普及。

  啟示三:維基百科里有一段解釋:

由于 JavaScriptMVC 不需要任何服務器端的配合,因此它可以和任何的網站服務接口與編程語言整合,如 ASP.NET、Java、Perl、PHP、Python 或 Ruby。

 

  這段話說明了前端MVC的一個很重要的特點就是前端MVC可以擺脫服務端語言的束縛做到真正的獨立,同時前端MVC又可以和任何服務端語言進行整合,大家可以試想下如果我們開發的web應用前端達到了前端MVC的程度,那么公司在招聘web前端工程師的時候就不在會問你“你會java嗎?”或者“你會php嗎?”假如這個前端工程師所會的服務端語言能力和公司不匹配,面試官也不會再猶豫和搖頭了。

  啟示三同時還隱含了一個問題,為什么好的前端MVC框架可以做到和任何服務端語言配合呢?這個解決手段之一我在前文中的第一階段前后端分離方案里就提到了,那就是解決報文格式的統一和交互接口的統一的技術手段,只有這樣前端MVC和服務端的靈活對接就不會再是問題了。但是僅僅這個手段還是遠遠不夠的,我們要達到這個需求還需要解決一個問題,這個問題就是要把服務端MVC霸占web前端的工作也要搶回來。那如何搶呢?

  上篇文章里我分析過服務端MVC的視圖層的問題,服務端MVC的視圖層技術例如java里的jsp技術,這個技術是將html和java代碼整合的技術,java的web容器把jsp解析完畢后最終生成為html文件發送給瀏覽器,瀏覽器在解析這個html將最終效果展示給用戶。那么我們要搶回服務端霸占的web前端的工作我們就得分析下這些動態頁面技術到底做了哪些事情特別是侵占web前端的事情。

  這里首先我們要談談服務端在動態頁面里的作用,其實服務端為動態頁面作用很單一就是提供了網站需要展示的數據而已,服務端是不會創造一個新頁面的。服務端提供的數據的類型也是很統一,要不就是服務端語言提供的基本數據類型例如:字符、數字、日期等等,要不就是復雜點的數據類型例如數組、列表、鍵值對等等,不過歸屬服務端的動態頁面還需要服務端語言幫助做一件事情,那就是把服務端提供的數據整合到頁面里,最終產生一個瀏覽器可以解析的html網頁,這個操作無非就是使用服務端語言可以構造文件的能力構建一個符合要求的html文件而已。不過一個頁面里需要動態變化的往往只是其中一部分,所以做服務端的動態頁面開發時候我們可以直接寫html代碼,這些html代碼就等于在構造頁面展示的模板而已,而模板的空白處則是使用服務端數據填充,因此在java的web開發里視圖層技術延生出了velocity,freemark這樣的技術,我們將其稱之為模板語言的由來。

  由此可見,服務端MVC框架里搶奪的web前端的工作就是搶占了構建html模板的工作,那么我們在設計web前端的MVC框架時候對于和服務端對接這塊只需要讓服務端保持提供數據的特性即可。從這些論述里我們發現了,其實前端MVC框架要解決的核心問題應該有這兩個,它們分別是:

  核心問題一:讓模板技術交由瀏覽器來做,讓服務端只提供單純的數據服務。

  核心問題二:模板技術交由瀏覽器來承擔,那么頁面的動態性體現也就是根據不同的服務端數據進行頁面部分刷新來完成的。

  而這兩個核心問題解決辦法那就是使用ajax技術,ajax技術天生就符合解決這些問題的技術手段了。

  要讓web前端承擔模板技術,就得使用javascript的模板技術,時下javascript的模板技術可謂是百花齊放,百家爭鳴,很多朋友曾為這些技術稱奇,其實探求它的本源無非就是用javascript為基礎實現了個jsp,velocity而已,如果有朋友還沒接觸過javascript模板技術,可以在百度里搜索下【javascript模板引擎】,本文這里就不展開談論了。

  前端的MVC討論到這里又出現了一個新的疑問,我上面講到解決前端MVC兩大核心問題的手段是ajax技術,ajax是異步請求,那么這是不是就是說讓網站全部使用異步請求我們就可以實現前端MVC,并且解決網站所有的問題呢?

  這個問題的回答當然是不可能的。一個網站是永遠沒法擺脫與異步請求相對的同步請求,就算有個網站把異步做到了極致,但是它也無法擺脫用戶第一次訪問要在瀏覽器地址欄填寫網站入口頁面url地址的同步請求問題,網站把異步操作做到極致也無非就是把網站做成了一個純粹的單頁面形式而已。

  純粹單頁面的網站很多人一聽到就覺得好牛逼啊,很前衛,很厲害,對前端有所了解的人還會想到單頁面也就意味要運用更多的javascript編程和DOM編程,前端代碼難度也會大大增強,好的單頁面應用如果這個應用還包含復雜的業務邏輯,那么單頁面前端開發里很可能還會使用到如今很火爆的javascript模塊技術例如requirejs或者seajs技術,單頁面聽起來實在太完美了,但是我們冷靜下來思考下,單頁面真的完美嗎?下面我要為單頁面潑潑涼水了,具體如下:

  潑涼水一:單頁面其實指的是網站只有一個入口,但是并不代表用戶看到的網頁就是一個樣子的,單頁面里也會有很多頁面切換,但是不管頁面里的模樣如何變化,瀏覽器地址欄的地址都不會變化,能做到這點就得歸功ajax的超強能力了,單頁面不同模樣的展示都是在javascript代碼里實現的,那么問題來了,單頁面對于搜索引擎的網絡爬蟲就非常不友好了,因為網絡爬蟲是根據url抓取頁面,抓取完畢后會忽略javascript代碼,那么單頁面的設計方案就會導致SEO優化只能作用于首頁,而網站其他頁面將無非有效的被SEO技術進行優化。

  潑涼水二:一個網站做成單頁面以后那么網站不同的展示都在一個url下面,但是如果有些用戶只是對網站的某一部分功能很感興趣,而這部分功能又不是被單頁面的唯一同步請求所展示的首頁里的內容,那么結果就是這些用戶每次登陸網站時候都要手動操作一下才能進入自己想要的功能頁面里,假如首頁進入功能頁面的操作步驟比較繁瑣,那么這個必然會導致網站用戶體驗的下降。

  那么上面的問題該如何來破呢?

  這里我首先來講講第二個問題的解決方案,第二個潑涼水的問題的核心就是要記錄單頁面的狀態問題,這個狀態可以幫助首頁能快速切換到具體的功能頁面,要讓客戶端網頁有狀態最常用的手段就是cookie了,如果瀏覽器支持html5,那么保存狀態的手段就更多,能力也更強了。但是這種手段是和客戶端緊耦合的,那么如果碰到這種情況,該手段就會出現問題了,例如如果有個人發現單頁面網站里一個很有趣的功能,這時候他正好和朋友QQ聊天,他告訴了他的朋友,他的朋友也該興趣,讓他把鏈接發過來,那么這個朋友就不得不在從首頁在重復操作一遍,由此可見,cookie的手段并沒有全面解決這個問題,那我們還有其他手段嘛?

  答案是還真有,那就是使用html的錨鏈接,錨鏈接的形式如下所示:

http://www.baidu.com/#sharpxiajun

 

  下面是我摘抄下百度百科對錨鏈接的解釋:

錨鏈接實際上就是鏈接文本,又叫錨文本。可以理解為:帶有文本的超鏈接,就叫錨鏈接。錨文本可以作為文本鏈接所在的頁面的內容的評估。

一般的來講,網站頁面中增加的錨鏈接都和頁面本身的內容有一定的必然聯系。網站建設的行業網站上會增加一些同行網站的鏈接或者一些做網站建設的知名設計網站的鏈接;

另一方面,錨文本能作為對所指向頁面的評估。錨文本能精確的描述所指向頁面的內容,個人網站上增加Google的鏈接,錨文本為 “搜索引擎”。這樣通過錨文本本身就能知道,Google是搜索引擎。

 

  那么在單頁面里的功能切換時候我們改變一下url上的錨文字,反過來說使用錨文字做路由器,讓其可以路由到對應的功能頁面那么上面的問題不就可以解決了。關于錨鏈接我這里要補充一些知識,首先錨鏈接的形式是url#文字,錨的起始標記是#號,這個#號的內容其實是屬于瀏覽器端的,也就是說#包括#號后面的內容是不會被發送到服務端的,那么我們想改變錨鏈接只能在客戶端進行,但是傳統的錨鏈接的變化是很難被javascript語言監控到的,直到html5的出現才從根本上解決了這個問題,html5提供了hashchange事件,該事件可以監控錨鏈接的變化,因為javascript語言可以監控錨鏈接的變化,那么使用錨鏈接路由功能頁面就成為了可能,那么低版本的瀏覽器該怎么辦了?這個主要是ie的問題了,其實ie8包括ie8都支持hashchange事件,再低就不行了,不過jQuery有個插件可以讓低版本的ie支持hashchange事件,有興趣的童鞋可以百度下啊。

  看來潑涼水二問題是有解的,那么潑涼水一怎么解決了?我的回答是基本無解,這個問題的關鍵在網絡爬蟲這邊,如果我們被動解決這個問題,那只能是拋棄javascript了,這個玩笑就開大了,所以我們只好祈求各大搜索引擎能不能智能化再厲害點了。這里加個題外話,我最近幾天突然意識到一個問題,那就是講到web前端技術我一定要加強對SEO的思考,因為絕大多數網站都會把搜素引擎當做入口的生命線,這是一個很難回避的問題,不管我們網站做的如何優秀,假如用戶很難找到它,那一切都將會是百搭,而在前端設計里要加入SEO的思考,這必然會導致整個架構的重大變化。這個問題我會在以網站靜態化角度審視前后端分離方案時候重點講下。

  前端MVC討論到這里我們會發現我們的談論里缺了一環那就是MVC的M層模型層,web前端要侵入到模型層了,這不就等于web前端要造反了,它不僅僅想改變從屬服務端的悲慘命運,還要搶奪服務端的部分功能,讓服務端成為瀏覽器對應的存儲系統,這不是無異于虎口奪食,在時下服務端如此強勢的大環境下,這種想法簡直就是活得不耐煩了,哈哈,當然這是戲言了,做技術做工程還是要講求個合理性和邏輯性的,技術和工程都是實在的東西很講道理的,只要道理站得住腳怎么個做法都是其次,回到問題本身,我個人覺得在PC端討論web前端做模型層其實往往利大于弊,就安全而言,模型層意味有大量業務邏輯推移到web前端,那么安全的保障難度會加大,就技術難度而言,web前端做模型層會讓javascript編程巨復雜,所以要做這個抉擇時候一定要結合業務做仔細的權衡,其實我現在接觸的一些說包含模型層能力的前端框架在實際運用里模型層的功能還是使用太少,不過這個問題如果放到移動端,或者是PC和移動端融合可能就會有些不同,這個問題我將在本系列的終篇里再談談,這里也不累述了。

  說到這里需要總結下了,前端的MVC不應該等于單頁面開發,前端MVC也不是把ajajx用到極致,根據實際業務場景,我們需要適當的把同步請求和異步請求結合起來。如果前端MVC里包含了更多同步請求,那么對于MVC里的C層即控制層就會有更高的要求。前后端分離主題還有個下篇,下篇里我還會提到一種前后端分離方案那就是nodejs的運用,而nodejs的運用就是和控制層有密切的關系,上篇里我提到nodejs是前后端分離方案的催化劑,其實我個人認為nodejs參入的前后端分離方案才是更加完美些的前后端分離方案,這個完美的評價原因之一就是從前端承擔控制層作用角度思考的,所以前端控制層這個內容我將放在下篇討論。

  好了,本篇寫完了,從本篇我們可以看到前端MVC的歷史很早,它的出現早于nodejs,這就說明前端MVC其實并不是什么新技術,只不過是現在才被大家重視起來,完善它的人也越來越多。從本篇我們還發現前端MVC其實并不完美,問題很多,最致命的就是對網絡爬蟲的不友好,所以我們需要考慮到SEO技術參入其中的前后端分離方案。

  最后,祝大家晚安了。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()