小劉同學的項目采用的是前后端分離架構,現在前后端程序猿已經碰過面,協商好了一些前端需要的數據接口,於是前后端程序猿同時開工碼代碼。
這時候小劉同學某個頁面需要后端數據,但是后端叔叔還沒有將該數據的借口開發出來,此時小劉只能做假數據(專業點叫 mock數據 ,^_^),但是小劉的ajax的借口寫的是與后端叔叔商量好的絕對路徑(域名+請求路徑+請求參數,跨域問題已解決),因為這是以后真正的請求路徑,所以小劉又不像先寫本地相對路徑,后期再來修改(萬一后台叔叔開發的慢了,鬼知道有多少接口要修改呀)。於是他就迷茫了。。。
仔細看看這其實就是前后端分離中的mock數據和聯調的問題,就現在來說能解決的方式有很多種。先說mock數據,gulp,webpack, fekit (去哪兒網的一款前端自動化構建工具,據說歷史比webpack和gulp都要久遠)等等自動化構建工具都有mock數據的功能,這不是問題;再說絕對路徑的問題,其實只需要做一個host的映射就行了。
進入正題,前后端聯調。
什么是前后聯調
我的理解是 前后端聯調 是一種 真實業務數據 和 本地mock數據 之間來回切換以達到前后端分離架構下的不同開發速度時數據交換的一種方式方法(有點繞)。
為什么要前后端聯調
前面解釋前后端聯調是可能有些繞,這里舉例來說明一下。
回到上面小劉的問題,假設小劉現在ajax中的url寫的是相對路徑(如:./mock/user.json),小劉現在面臨的是后端接口沒有數據,需要本地mock數據,但是當后端接口開發完成,並且有了測試數據后,小劉是不是需要切換到后端數據呢?答案是肯定的,但是小劉需要在本地mock數據和后端接口數據之間來回切換,為什么呢?很明顯嗎,本地的mock數據是小劉自己寫的,肯定符合前端需求,但是后端接口首先需要測試通不通?還需要測試數據格式對不對?有可能前兩部都整好了,但是后端還沒有填寫足夠的數據(比如,列表頁,小劉想分頁,后端叔叔就寫了兩條測試數據,你咋整?),所以呀,小劉需要根據后端叔叔對接口的調整不斷的來回切換url,這樣豈不是還在受后端的影響,還談毛線前后端分離呀!
所以當我們在前后端分離架構中, 不斷來回切換本地mock數據和后端接口數據時 就遇到了聯調的問題。
實現前后端聯調
首先我們已經知道,在現在流行的 “前后端完全分離” 架構中,前后端聯調是一個不可能避免的問題,就我目前對前后端聯調的理解來說,我認為需要聯調的有以下兩個方面的資源:
- css、js、圖片等前端靜態資源文件。
- ajax獲取的后端數據。
而前后端分離的架構的應用可能也分為兩種情況:
- 前后端完全分離,前后端分別擁有自己的域名和服務器。
- 前后端開發分離,但是部署時是一個域名和一台服務器。
還有就是需要聯調的場景也是兩種情況:
- 開發階段
- 調試階段
針對以上2方面資源和2種應用情況還有2種場景(2到家了。。。),接下來我們看看怎樣通過mock數據和host的映射來實現解決這些問題。
先解釋一下 ‘222’
2種資源
為什么我將資源分為兩種呢?首先來看css、js文件和圖片是通過link、scripts、img標簽來引入的(樣式中的圖片也是一個道理), 它們是不存在跨域問題的,你在哪里引入都無所謂。
而ajax獲取后端數據是有跨域問題的,雖然說可以解決,但是有可能是該數據(或者后端部署環境)和上面的css、js、圖片等靜態資源是不在同一台服務器上的,也可能是同一台服務器不同域名下的,如果都在同一域名同一服務器下,開發階段肯定也不在一起吧!
2種應用情況
雖然架構可以采用前后端分離,但是部署有可能就不一樣了,這和項目的大小,公司的情況等等都有關系了,一個百八十人用的小系統,還得兩台服務器兩個域名,你不覺着浪費嗎?
2種不同的部署情況直接導致了前期在設計聯調方案的時候就不同了,下面會詳細介紹。
2種開發場景
這不用多說了,雖然現在主張前后端分離,但也不能不和后端叔叔親近親近了呀,不然誰給你數據區,所以說真個開發階段都可能遇到聯調的問題。
聯調開始
在講解聯調之前,你需要了解主流自動化構建工具本地mock數據的方法,本例以gulp來講解,不了解的小伙伴可以看看Gulp和Webpack對比的mock數據部分。
開發階段
兩台服務器對應兩個域名
這是最nice的方案,也是聯調最舒服的方式。
在這種方式下,前后和后端各有各的服務器和域名。后端會把他們開發的后端業務代碼,實時的上傳到服務器上(也可能不是,如放在后端叔叔自己的電腦上,實現是一樣的,只不過域名變成了叔叔的ip地址);而我們前端的代碼會實時的上傳到我們前端的服務器上(同理也可能在自己的電腦上,開發完一塊上傳)。
為了后面方面講解,前端服務器域名為“chping.website”,后端服務器域名為”chping.site”。
css、js和圖片等靜態文件
此時,我們的靜態文件的請求路徑建議使用我們前端服務器的絕對路徑,為什么呢?因為如果我們寫本地的相對路徑,等把我們的入口文件交給后端后,路徑還是絕對路徑,豈不是成了后端服務器的路徑了,那就壞菜了,還得一個一個修改成我們前端的絕對路徑(如: http://chping.website/css/reset.css
)。
那可能有小伙伴說,這樣的話,我在開發階段,我們的服務器上還沒有自己的靜態文件呢,去請求的話,會報404的!
對的,這時候就該我們的host的出場了,我們知道當進行域名解析的時候,第一步是在瀏覽器緩存中尋找,如果沒找到,第二步在我們系統的緩存中尋找(就是本地的hosts文件),然后….(想詳細了解請看網絡請求過程掃盲的DNS解析部分)就沒有然后了。既然域名解析需要通過hosts文件這一步,那么我們就修改一下它,讓訪問 http://chping.website
這個域名的請求,全都訪問我們本地的mock數據就好了呀!
在hosts文件中添加下面這一條
127.0.0.1chping.website
好的,搞定,從此以后所有訪問域名 http://chping.website
的請求都會被映射到本地了,然后再結合gulp的mock數據,就完成了你寫的是域名+絕對路徑(如: http://chping.website/css/reset.css
),但是請求的卻是你本地mock的數據(上面的請求會被映射到 http://localhost/css/reser.css
)。這樣你就不需要來回修改請求路徑了^_^。
ajax后端數據
開發工程中,靜態文件的聯調問題可能還是比較少的,特征也不明顯。但是通過ajax獲取后端數據使用聯調的情況可就多了去了,前面 為什么要前后端聯調 一節中已經通過小劉的例子說明了,就不在贅述了。
其實在介紹完 css、js、圖片等靜態文件 一節,相信你也能猜到了怎么去前后端聯調了。很簡單,ajax中的請求還是寫絕對路徑(如: http://chping.site/userlist
,獲取用戶列表),此時后端接口如果沒有開發好,和上一節一樣通過hosts文件的修改可以實現 chping.site
域名映射到本地來。如果后端像讓你給他測試一下接口獲取的數據對不對,你可以在修改一下hosts文件就可以了。
可能還有小伙伴問了,這樣還不是改來改去,麻煩死了。首先來說,相比較你修改多個url地址和修改一個hosts文件,孰輕孰重,一目了然;其次,怎么可能讓你去每次都去修改hosts文件呢,麻煩死了。現在向大家推薦一款小插件,在google商店里搜索一下 HostAdmin 就找到它了,下載安裝就好了,然后簡單配置一下你的hosts地址,就可以愉快地切換hosts的映射了(HostAdmin的使用自行google,干這行豈能不會用軟件)。
好了,兩台服務器對應兩個不同域名的場景在開發階段就這樣愉快地結束了。但是在實際開發中,中小公司很少給你兩台服務器和兩個域名的,一般正常情況就是一台服務器一個域名的。
一台服務器一個域名
我仔細想一下,此時這個服務器會給誰管理呢?
想都不用想肯定不是前端,后端叔叔比你對服務器熟悉多了,交給你去管理那是出鬼了(我還真遇到過,不過也是給后端首先使用,最后才把前端的代碼放到服務器上),所以說在這種情況下,你就老老實實在本地開發就行了。
css、js和圖片等靜態文件
這時候的靜態文件再開發階段不需要任何考慮,按照你喜歡的相對路徑或者相對於項目的根路徑的形式寫就行了,因為早晚還得交給后端。但是,需要注意:
- 如果你采用 相對項目根路徑的書寫方式來寫你的靜態文件路徑 時,一定要先和后端叔叔商量好,將來項目部署的時候他會把你的前端整個項目放在哪里?如果不是根目錄下,你就掛了。比如:你的reset.css的路徑時
/exports/styles/common/reset.css
,后端叔叔把你前端項目放在了根目錄下的frontEnd
文件夾下,reset.css
文件就報404了。 - 如果后端采用的java,你需要特別注意的是, tomcat的根目錄 並不是
webapps
文件,而后端項目默認是部署在webapps/ROOT
文件下的,所以你如果使用了相對項目根路徑的書寫方式來寫你的靜態文件路徑時,對不起又是404了。
ajax后端數據
因為現在唯一的一台服務器還是在后端叔叔那里,所以此時你還是可以寫絕對路徑(域名+請求路徑),利用hosts文件來改變域名映射實現聯調。
開發階段小結
其實在開發階段做聯調的情況還是很少的,一般都在自己的機器上開發,后端會自己做單元測試,根本不用前端來給他做測試的(先別罵,完事一塊,哈哈);而前端更不需要了,都在自己機器上開發。及時有兩台服務器和域名,有幾個每開發一個功能就上傳服務器呀(此服務器指項目上線時部署的服務器),有病吧!所以說,在這個階段只需要做好hosts映射就行了,不會讓你來回切換域名映射的。
但是接下來的調試階段就不一樣了,項目前后端大體都已經開發完成了,Beta版本已經部署了,這時候如果出現bug就需要頻繁的線上線下(真實數據和mock數據)切換了。
調試階段
調試階段的情況說明剛才提了一下,現在再詳細的闡述一下:
首先,已發布的Beta版本在測試的時候,發現前端頁面上有個地方有個小bug,需要你修改一下,於是你訪問線上的頁面,看了一下這個bug,發現是某個css樣式文件里面出錯了,於是你希望在本地修改,然后線上版本可以直接查看,這樣就可以實時看到你的修改在線上的真實樣子了。
兩台服務器兩個域名
這里就不在分靜態文件和后端數據分開介紹了,其實道理都一樣的,另外此時后端數據都是真實的了,也不需要你管后端了,此時你本地的mock數據已經下崗了。
首先你只需要打開前面你安裝的 HostAdmin ,通過它配置一下你的hosts文件(如果年前面的做了,此時你已經配置好了),然后 chping.website
這個域名你可以在本地和線上之間來回切換了。
再具體一點就是:
- 啟動你本地的項目
-
將
chping.website
域名通過HostAdmin設置為127.0.0.1 chping.website # 202.201.112.232 chping.website //假設202.201.112.232是線上服務器的ip
-
打開瀏覽器,並清除一下瀏覽器緩存,重新打開你們開發的網站。此時網站是獲取到的靜態資源就是從你本地獲取的了,但是ajax獲取的數據確實后端返回的真是數據。
- 然后你開始修改bug,這時候線上的版本可以實時查看你修改的前端內容,修改完bug,QA說了OK,你就可以把修改的文件替換掉服務器上的版本就行了。
一台服務器一個域名
這種情況就復雜了,此時只有一個域名,如果你開發階段是按照我前面說的,寫的是相對路徑,那么此時你是沒有辦法實現 兩台服務器兩個域名 那種線下修改,線上查看的高大上聯調的。那該怎么辦呢?
第一種方式就是,你在本地修改,本地查看,測試好了以后上傳到服務器,看看線上環境可不可以,OK當然好;不行就本地接着改,然后在上傳。
第二種方式就是,在開發階段你給靜態文件前面加上一個 假的域名 ,然后像兩個域名一樣進行假的域名 與本地映射配置,然后像兩個域名一樣開發。等部署的時候,在服務器上也暫時做一個本地映射,你就可以實現同兩個域名一樣的線下修改,向上查看了。但是,最后真正上線的時候,你就需要收到,把假域名全部刪掉。所以說,一台服務器一個域名的時候,前端靜態文件做聯調是很不方便的。
小結
總結一下, 前后端聯調 是一種 真實業務數據 和 本地mock數據 之間來回切換以達到前后端分離架構下的不同開發速度時數據交換的一種方式方法,而實現就是利用自動化構建工具的mock數據功能和修改域名解析文件hosts來實現的。
如果你的項目是兩台服務器和兩個域名,隨便你折騰。但是如果你是一台服務器和一個域名的話,就有些麻煩了,而這個麻煩僅對於你前端靜態文件聯調有影響,需要你好好思考一下怎么解決了,我目前還沒找到更好地方法去解決。