01
前面的話
如今我們使用的互聯網,客戶端與服務器端的交互無時無刻不在發生。比如我們在瀏覽器打開網頁,瀏覽器就是客戶端,將網頁數據發過來的也就是服務器。其實服務器,並沒有什么特別的,也就是一台晝夜不停運轉的電腦罷了。每一台入網的機器,都會被分配一個ip,我們可以通過ipconfig / ifconfig這樣的命令,知道我們電腦的ip地址。服務器本身,運行着服務器程序,他們監聽着來源於網絡的請求,並對請求進行響應。
比較常見的服務器程序,比如apache / Nginx / IIS等等,我們可以通過以下這樣的一個小的實驗,來了解網絡中的客戶端與服務器,是如何進行交互的。
實驗:一個小的局域網
第一步:運行你電腦上的服務器程序(以apache為例,建議使用xampp / wamp這樣的軟件包,win下一鍵安裝,能省不少事。當然,喜歡折騰的同學和SA們肯定要一個一個裝啦),在apache的www目錄下放入一些網頁文件,然后在瀏覽器的localhost下瀏覽網頁。
第二步:在電腦上打開wifi共享軟件,通過ipconfig / ifconfig命令查看本機在內網的ip,讓手機連接電腦共享的wifi(或者是兩者同連一個路由器的wifi),在手機瀏覽器的地址欄輸入電腦的ip,進入電腦的服務器並瀏覽網頁。
上面的小實驗的第二步,就模擬了一個簡單的瀏覽器+服務器系統(BS系統),也在一定程度上反映了網站基本的訪問原理。同時,這也是Web前端開發中真機測試移動端頁面的一個行之有效的方法;當然,你也可以通過這種方式,實現局域網絡的文件共享。
繼續深入一步,我們在瀏覽網站的時候很少使用ip直接訪問的,而是用www.baidu.com這樣的域名,域名與提供對應服務的服務器的ip地址通過DNS服務器相互對應。我們可以通過ping命令,也可以通過一些在線的工具,如http://ping.chinaz.com來獲取一個網站的ip地址,有時候ping出來的ip是不一樣的,一般和你使用網絡的地點有關,這主要是為了將對服務器的請求分流,減輕服務器的壓力,保證網站的訪問速度(比如可以了解一下CDN)。(web前端學習交流群:328058344 禁止閑聊,非喜勿進!)
02
開發的過程與設計的藝術
如何從0建立一個網站,這就涉及到軟件產品的開發了。一般,會有以下幾個職位。
產品(PM):負責對軟件產品的功能,目標用戶等許多部分,進行一個詳細的歸納整理,包括前期的功能地位和后期的功能修繕;
設計(UE):對用戶使用的產品界面、交互方式進行統籌和設計;
前端(FE):活躍於前端的程序員,負責使用代碼實現設計師的設計,並與后端協調數據在客戶端的渲染工作;
后端(BE):活躍於服務器端的程序員,為前端的渲染提供所需的數據;
系統(SA):保證開發過程中,對於服務器權限的管理與協調,以及服務器運行環境的提供,同時保證網站在生產環境中的平穩運行。
限於個人能力,我在此僅從前端和后端這兩個角度,探討網站實現的技術細節,其中會涉及許多具體的解決方案,供大家參考。
現在我們從這樣的角度去看一個網站,我將他分為三層,視圖層,數據層,以及控制數據在視圖上的顯示方式的控制器。
舉個例子,一個留言板,他的數據層會包括留言者的留言內容、留言時間、留言者的信息等內容。這些數據,就像一張excel表格一樣,存儲在我們的服務器。而我們的用戶肯定不希望看到一個簡陋的表格,他們希望看到的至少是一個界面,數據內容被清新美觀的顯示在我們的瀏覽器上,而這個界面,也會隨着數據內容的增刪修改而做出相應的調整。存儲表格數據的,就是數據層;用戶看到的,就是視圖層;讓界面隨數據產生改變,則是控制器的使命。
現在,從技術的角度我們去實現他。首先,前端工程師根據設計師的設計,做出視圖層的模板,后端工程師也做好相應的數據存儲工作,包括設計創建數據庫、數據表等等。現在,基本的工作完成。繼續下去,我們則有很多的選擇。
選擇一:后端渲染數據到視圖
這種方法,就是前端將模板交給后端,告訴后端具體在哪個位置放什么樣的數據,放的時候有什么具體的要求,剩下的渲染工作完全交給后端處理。這樣的方法實現起來門檻低,而且由於服務器計算性能一般情況下強於客戶機,后端來刷模板簡單粗暴速度快,沒有任何爭議。缺點是后端工程師由於處理了數據填寫的工作,相當於涉及了視圖層(即前端)的工作內容,導致分工不夠明確;同時,由於是后端更新數據,而后端代碼是運行在服務器上的,每次要更新都要刷新頁面重新請求一個完整的頁面,某種意義上來說,用戶體驗相對較差。
選擇二:后端將數據生成為小的數據文件,前端獲取數據並由前端更新視圖。
這種方法,涉及到前端的Ajax。說白了就是在后台異步加載另外一個頁面,在加載過程中用戶不會看到任何變化,而加載完成后,相當於在前端程序里獲取了一個字符串,剩下的任務就是將這個字符串解析取出里面的數據並將對應內容渲染到相應的位置上。通過這種方式,首先可以保證視圖層顯示的內容都完全由前端工程師負責,分工明確,實現了一定程度上的前后端分離;同時,與服務器交互的文件大小,從一整個頁面縮小到了一個僅僅包含要更新的數據的小文件,交互的量減小,帶來性能上的提升;另外,由於交互文件一般使用json這種多數編程語言都可以解析的數據格式,不僅可以給網頁前端使用,也可以給移動端app的前端開發使用,統一了接口,擴展時減小了工作量。
選擇三:單頁應用(SPA)
我先解釋一下單頁應用,和傳統網站相比,他更接近於移動端應用程序,其核心就是將路由控制在前端工程師的手里。核心技術除了上面的Ajax,還有pushState,又有人將兩者合稱為PJAX。
先說什么是路由,路由可以理解為你網站域名后面的內容,比如www.abc.com/p/123這樣的網址,后面的/p/123就標明了一個路徑。可以類比於我們電腦的磁盤,當我在路徑的位置輸入C:/p/123的時候,我希望看到C盤下p文件夾下123文件夾的內容,當123變成了456,顯示的內容應該有些變化。如果456文件夾存在,顯示該文件夾的內容;如果不存在,則會彈出錯誤信息提示不存在。對應我們的網站,如果當/p/123變成/p/456的時候,也應該給出對應的顯示。路由由前端控制的含義,就是說,網站url的變化與對應的顯示由前端處理。你的整個網站實際上只有一個頁面,前端根據url的變化,通過Ajax異步加載需要的數據,然后通過pushState操作瀏覽器的歷史記錄,達到與瀏覽普通網站同樣的效果。
SPA最大的優點,大概就是響應速度了。當然,使用SPA對前端的技術提出了相對比較高的要求。使用SPA的一般情況,是你要做一個類似於安卓app的網站,如淘寶的手機站和Gmail,都是相當典型的SPA。不過,雖然現在SPA很多,並不是所有的場景都適合使用SPA的。
淘寶收藏夾的架構:
作為訪問量如此高的網站,淘寶是怎么做的。(首先,php的后台肯定是擔負不起這樣的訪問量的。)在淘寶UED,他們介紹了“中途島”項目,基本架構是:前端工程師使用Node.js進行模板渲染,保證模板的渲染由服務器完成提高效率;Node.js訪問由java后台封裝的高級數據接口,而java在訪問數據庫的時候,則是使用C語言來實現最有效率的訪問。技術細節可以參考淘寶UED的博客。
03
項目開發中值得一提的點
關於查閱資料和提問:
遇到問題先問搜索引擎,這我想應該都沒有什么意見。用不了谷歌,可以從laod.cn下個hosts,翻出去的話,方法太多,不廢話了。
當然了,找不到具體問題問人是不可避免的。但是當問題比較復雜的時候,比如前端這邊處理瀏覽器兼容問題的時候,一定要有在線demo,一定要把問題描述的很清楚並且真的是自己解決不了了再問。關於提問的藝術,可以看看張鑫旭大神的博客(個人非常喜歡,強烈推薦前端同學關注),如何提問才能進階成為前端大神?,這篇文章對提問需要注意的點說的非常明確,請大家,無論是不是做前端,最好都看看。
任務進度管理:
雖然在學校里做東西,很少會有嚴格的工期安排、進度計划這些,但是在公司里,這些問題肯定是會遇到的。推薦幾個工具,大家可以了解一下:tower和微軟的project。
版本控制:
幾乎沒有任何成功的軟件項目,是一個敲代碼敲出來的,況且,就算是一個人敲代碼,也應該對自己所做的改動有所記錄和備份。在這里,我將介紹兩種使用git進行版本控制的方式,供大家參考。
分支管理:
整個項目是一個大的倉庫,這個大的倉庫由於不同的修改而有不同的分支。一般來說,有master(穩定發布版本) / dev(開發中的相對穩定版本) / 開發人員個人分支(集中個人的修改)這些。一般的工作過程為,個人會在個人的分支上修改,然后push到dev分支,穩定下來的dev分支作為新的版本再合並到master分支。那一部分出了問題,就在哪一部分進行修改。git在你每次更新分支的內容時都要求你輸入一段描述修改的文字,這在將來的版本控制和回退上都會很有幫助。
倉庫管理:
個人理解其實是擴大化的分支管理,項目負責人建立項目倉庫,項目開發人員fork母倉庫,做了自己的修改后,對母倉庫發出pull request,申請合並到母倉庫。這一方法最大的優點,就是方便負責人進行code review,保證代碼質量;同時也可以方便對開發人員的貢獻度進行考核。通常公司里會選取這種方式。
項目的持續集成:
持續集成大家在學校也很少會接觸到,但是當你在公司里,遇到大項目的時候,就肯定會接觸到持續集成這方面的需求和工具。個人認為持續集成更像是一種思想,在項目的開發過程中,前端和后端在開發過程中不斷的對接,測試樣例提前都做好,然后自動化構建項目,自動化測試等等。每當代碼庫更新(當然,本地構建失敗的代碼是不允許提交到倉庫的)的時候,自動構建腳本、自動測試腳本都會跑出一個更新后的產品給大家看,方便團隊中的每一個人掌握項目的情況和目前的進度。
實現這種思想,就需要與之配合的工具,關於持續集成這方面現在在企業中目前還沒有“最佳實踐”,不過確實有很多前人的經驗供咱們借鑒,如《持續集成最佳實踐》里面對於持續集成實踐進行了思考
04
幾點建議
在學習開發技術的過程中,個人給大家一點建議:
- 前期初學的時候,千萬不要求多
道理大家都明白,什么都想學肯定什么都學不好。如果一個人都能學過來,那么我們還搞這么多方向做什么。有些東西,當你需要的時候,自然就會接觸到;而那個時候你再學,你肯定是在實際項目中遇到了什么問題。有問題導向的學習是非常有效率的,所以千萬不要求多,穩住。
- 千萬不要剛剛入門就覺得自己什么都會了
這是我經歷過的階段,當時被一位學長拉了回來,也是非常幸運。這個階段你覺得自己清楚很多東西了,感覺只要查查資料自己什么都能解決。其實想一想,這么多人研究這個領域,你怎么可能馬上就看透了他呢。每個領域,都有很多坑,每一個坑也都會有至少一個與之對應的解決方案,而處理項目和解決方案,是一條漫長的道路。知識是越學越細的,本來你以為前端只能寫寫頁面,深入學習以后,你才會發現,js可以寫機器人;可以調系統API做桌面應用;哪怕只是在寫頁面這部分也有着頁面渲染時間、內存泄漏等各種各樣的問題和與之對應的層出不窮的解決方案。所以,低調,前面的路還很長。
- 學到一定程度,可以多去看看
我們知道書本上的知識肯定不是最新的,技術在不斷的發展。可能你現在用的書上的代碼都已經過時到運行不了了。這個,其實很正常,畢竟做網絡這方面,怎么可能光靠書來追蹤技術呢。所以多去看吧,github,各種社區、論壇,線下的技術交流,這些可以給你帶來最新鮮的養分。所以,世界這么大,出去多看看。
05
結語
寫代碼,按照自己的意願去構建一個產品,一個項目,哪怕再小,依然是自由的。哪怕是在實現別人的需求,可以做好,做精,做出一套最佳的解決方案(沒有最佳,只有最適合項目),給別人留下輪子去做好二次開發,依然是自由的,是有意義的。