1. 程式人生 > >關於大型網站技術演進的思考(十五)--網站靜態化處理—前後端分離—中(7)

關於大型網站技術演進的思考(十五)--網站靜態化處理—前後端分離—中(7)

  上篇裡我講到了一種前後端分離方案,這套方案放到服務端開發人員面前比放在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技術參入其中的前後端分離方案。

  最後,祝大家晚安了。

相關推薦

關於大型網站技術演進思考--網站靜態處理前後分離7

  上篇裡我講到了一種前後端分離方案,這套方案放到服務端開發人員面前比放在web前端開發人員面前或許得到的掌聲會更多,我想很多資深前端工程師看到這樣的技術方案可能會有種說不出來的矛盾心情,當我的工作逐漸走向越來越專業化的前端開發後,我就時常被這套前後端分離方案所困惑,最近我終於明白了這個困惑的本源在哪裡了,那

關於大型網站技術演進思考--網站靜態處理前後分離—上6

  前文講到了CSI技術,這就說明網站靜態化技術的講述已經推進到了瀏覽器端了即真正到了web前端的範疇了,而時下web前端技術的前沿之一就是前後端分離技術了,那麼在這裡網站靜態化技術和前後端分離技術產生了交集,所以今天我將討論下前後端分離技術,前後端分離技術討論完後,下一篇文章我將會以網站靜態化技術的角度回過

關於大型網站技術演進思考--網站靜態處理前後分離—下8

  我第一次聽說nodejs技術大概是在2009年年末,不過我真正認真在網路上進一步瞭解nodejs還是在2010年年中,當時對nodejs的認識和我現在對nodejs的認識有著天壤的區別,開始想了解nodejs我只是為了感慨谷歌公司開發的V8引擎居然如此強大,它不僅僅可以作為chrome瀏覽器的javasc

關於大型網站技術演進思考--網站靜態處理—滿足靜態前後分離9

  前後端分離的主題雖然講完了,但是前後端分離的內容並沒有結束,本篇將繼續前後端分離的問題,只不過這次前後端分離的講述將會圍繞著本系列的主題網站靜態化進行。在講本篇主題之前,我需要糾正一下前後端分離主題講述中會讓朋友們產生誤導的地方,這種誤導就是對時下流行的一些前後端分離方案(沒有使用nodejs的前後端分離

關於大型網站技術演進思考--網站靜態處理—web前端優化—上11

對於一個網路請求的處理,是由兩個不同型別的操作共同完成,這兩個操作是CPU的計算操作和IO操作,如果我們以處理效率角度來評判這兩個操作,CPU操作效率是光速的,而IO操作就不盡然了,計算機裡的IO操作就是對儲存資料介質的操作,計算機裡有如下幾個介質可以儲存資料,它們分別是:CPU的一級快取、二級快取、記憶

前後分離實踐

就是 經驗 靜態頁 局限 工具 服務器 png 開發人員 技術 前言 最近這一段時間由於Nodejs的逐漸成熟和日趨穩定,越來越多的公司中的前端團隊開始嘗試使用Nodejs來練一下手,嘗一嘗鮮。 一般的做法都是將原本屬於後端的一部分相對於業務不是很重要的功能遷移到Nodej

淺談前後分離的跨資源共享CORS

簡介 當下無論大廠小廠的前後端開發模式都是前後端分離。以前遇到通過jsonp解決跨域的方式也漸漸的淡出的工程中(不瞭解jsonp的可以看JSONP跨域請求+簡答實現百度搜索)。當前端請求一個介面的時候就會引起跨域,但是當下的前端構建工具都有相應的解決方案,比如webpack中web-dev-server這個

關於.net專案前後分離框架

.net前後端分離專案,主要就是呼叫WebApi介面實現連線。 主要程式需要AJAX實現, $.ajax({ type: 'post', url:  '/api/Controller/action', data: { UserGuid: userguid}, async: true, succ

dotnetcore+vue+elementUI 前後分離前端篇

                        &n

無意間做了個 web 版的 JVM 監控前後分離 React+Spring Boot

之前寫了JConsole、VisualVM 依賴的 JMX 技術,然後放出了一個用純 JMX 實現的 web 版本的 JConsole 的截圖,今天原始碼來了。 本來就是為了更多的瞭解 JMX,第一步就想把所有的 MBean 和屬性都展示出來,開始在控制檯輸出,但是效果不好,內容太多太長,不夠直觀,然後就加了

關於大型網站技術演進思考--存儲的瓶頸5

做了 技術分享 表數 例子 執行 同時 設備 系統重啟 拆分 原引:http://www.cnblogs.com/sharpxiajun/p/4265853.html 上文裏我遺留了兩個問題,一個問題是數據庫做了水平拆分以後,如果我們對主鍵的設計采取一種均勻分布的策略,那麽

關於大型網站技術演進思考--網站靜態處理—動靜整合方案2

  上篇文章我簡要的介紹了下網站靜態化的演進過程,有朋友可能認為這些知識有點過於稀鬆平常了,而且網站靜態化的技術基點也不是那麼高深和難以理解,因此它和時下日新月異的web前端技術相比,就顯得不倫不類了。其實當我打算寫本系列的之前我個人覺得web前端有一個點是很多人都知道重要,但是有常常低估它作用的,那就是we

關於大型網站技術演進思考--網站靜態處理—動靜分離策略3

  前文裡我講到了網站靜態化的關鍵點是動靜分離,動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。由此可見,網站靜態化處理的核心就是動靜分離和快取兩大方面,上篇我簡單講述了動靜整合

關於大型網站技術演進思考--網站靜態處理—反向代理10

  反向代理也是一種可以幫助實現網站靜態化的重要技術,今天我就來講講反向代理這個主題。那麼首先我們要了解下什麼是反向代理。和反向代理相對應的是正向代理,正向代理也就是我們常說的代理服務,正向代理是非常常見的,例如在某些公司裡我們想使用網際網路,那麼我們就得在瀏覽器裡設定一個代理伺服器,通過代理伺服器我們才能正

關於大型網站技術演進思考--儲存的瓶頸5

  上文裡我遺留了兩個問題,一個問題是資料庫做了水平拆分以後,如果我們對主鍵的設計採取一種均勻分佈的策略,那麼它對於被水平拆分出的表後續的查詢操作將有何種影響,第二個問題就是水平拆分的擴容問題。這兩個問題在深入下去,本系列就越來越技術化了,可能最終很多朋友讀完後還是沒有找到解決實際問題的啟迪,而且我覺得這些問

關於大型網站技術演進思考--網站靜態處理—快取4

  上篇我補充了下SSI的知識,SSI是一個十分常見的技術,記得多年前我看到很多入口網站頁面的字尾是.shtml,那麼這就說明很多入口網站都曾經使用過SSI技術,其實現在搜狐網站也還在用shtml,如下圖所示:     由此可見SSI在網際網路的應用還是非常廣泛的。其實網際網路很多網頁如果我們按照動靜分離

關於大型網站技術演進思考:儲存的瓶頸5

上文裡我遺留了兩個問題,一個問題是資料庫做了水平拆分以後,如果我們對主鍵的設計採取一種均勻分佈的策略,那麼它對於被水平拆分出的表後續的查詢操作將有何種影響,第二個問題就是水平拆分的擴容問題。這兩個問題在深入下去,本系列就越來越技術化了,可能最終很多朋友讀完後還是沒

關於大型網站技術演進思考--儲存的瓶頸2

  上篇裡我講到某些網站在高併發下會報出503錯誤,503錯誤的含義是指網站服務端暫時無法提供服務的含義,503還表達了網站服務端現在有問題但是以後可能會提供正常的服務,對http協議熟悉的人都知道,5開頭的響應碼錶達了服務端出現了問題,在我們開發測試時候最為常見的是500錯誤,500代表的含義是服務端程式出

關於大型網站技術演進思考--網站靜態處理--總述1

  在儲存瓶頸的開篇我提到像hao123這樣的導航網站只要它部署的web伺服器數量足夠,它可以承載超大規模的併發訪問量,如果是一個動態的網站,特別是使用到了資料庫的網站是很難做到通過增加web伺服器數量的方式來有效的增加網站併發訪問能力的。但是現實情況是像淘寶、京東這樣的大型動態網站在承擔高併發的情況下任然能

關於大型網站技術演進思考--儲存的瓶頸6

  在講資料庫水平拆分時候,我列出了水平拆分資料庫需要解決的兩個難題,它們分別是主鍵的設計問題和單表查詢的問題,主鍵問題前文已經做了比較詳細的講述了,但是第二個問題我沒有講述,今天我將會講講如何解決資料表被水平拆分後的單表查詢問題。   要解決資料表被水平拆分後的單表查詢問題,我們首先要回到問題的源頭,我們