首先請讓我描述一下我們這一代的web。
這是一個HTML5的時代,這是一個javascript獨當一面的時代,這是一個前端和後端分庭抗禮的時代。
說起javascript在前端,很多人馬上會說,MVVM,angular,backbone,avalon,react,...
沒錯這些都是優秀的javascript框架,都可以獨當一面做出優秀的作品。但試想一下這樣的場景:開發是分工的,web界面原型由美工提供,我們程序員往靜態頁面加入動態內容合成最終的web內容。表面看來很正常,但卻是無盡蛋疼的開始。當我們完成一個版本以後,需求改了,加個橫幅,加個彈框之類。美工在原來的版本上做了修改,我們跟進改動,這是相當痛苦的一件事,要了解美工改了什麼,每個tag,css,js怎樣影響頁面元素和行爲。我要是都懂了,美工可就擔心了...
這裏要講的是針對這種場景的解決方案。靜態前端由美工負責,數據後端由程序員負責。每個頁面由程序員只寫很少的js將數據應用到頁面上,可以方便地切換回原版供美工再修改。後端程序只提供json格式的數據,同源的用ajax,跨域的用jsonp,頁面收到數據後更新對應的內容。部署時,靜態的頁面放在apache,動態的程序放在tomcat或weblogic,這樣還可以平衡負載,減輕應用服務器的壓力。
這種思路不錯,但要想玩得轉還得過幾關,以下一一討論:
1. 初始化數據
試想一個product.html?id=123的請求發到apache,靜態的product.html被返回到了瀏覽器。渲染這個html的時候,一個product.do的請求自動發到tomcat要拿數據。這時怎樣知道id=123呢,看request header中的referer就可以了,當然要自己分析提取。如果你想讓等待的時間儘量少,可以在渲染html時同時拿數據,回頭再做一個同步處理。例如:
<head> ...// load jquery <script> var prdData = null; var synFlag = false; $.post('product.do',{},function(data){ prdData=data; initData(); }, 'json'); </script> </head> <body> ... <script> synFlag = true; initData(); function initData(){ if (synFlag && prdData != null) { ... } } </script> </body>
2. 國際化I18N
將Message分成兩類,異常顯示的信息,這類做法和以前的一樣用服務器程序處理。正常顯示的信息(例如label)就用js來做。寫一個js文件,例如i18n.js
var i18n = { en : { title:"title", name:"name",... }, zh : { title:"標題", name:"名稱",... } }
寫一個加載i18n的函數
function loadI18N(locale) { var msgs = i18n[locale]; $('#title').text(msgs.title); $('#name').text(msgs.name); }
切換locale,不需要請求數據,但需要告訴服務器,當前的語言
function switchLocale() { locale = locale == 'en' ? 'zh' : 'en'; $.post('locale.do', {locale:locale}); loadI18N(locale); }
3. 頁面嵌套
以前用jsp或者freemaker時,用include,import等很方便。現在這種情況如何處理呢?有兩個方法
方法一:jquery.load()
加載初始化數據之後,獲得了locale,然後$('#target').load('target_'+locale+'.html')
方法二:CSS
方法一要經過兩次請求,有時會覺得慢。想快一點的話可以將中文、英文兩個版本都寫在第一個html上,設 style="display:none",當加載初始化數據之後,用$('#target_'+locale).show() 將之顯示出來。
4. 表單提交
表單數據肯定是異步提交的,服務器程序返回成功標誌或者錯誤信息。如果是錯誤信息則顯示在對應位置,如果是成功標誌則用js跳到下一個頁面。