首先请让我描述一下我们这一代的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时同时拿数据,回头再做一个同步处理。例如:


...// load jquery



...


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跳到下一个页面。