多子站站点的URL方案

 

假如你有个地域性很强的导购网站,在北京有个子站,在杭州又有一个,两个子站在后台对应单个JAVA应用。这时你会怎么设计URL的结构以区别不同的子站? hangzhou.hello.com/xxx代表杭州,beijing.hello.com/xxx代表北京;或者是hello.com/hangzhou/xxx代表杭州,hello.com/beijing/xxx代表北京;或者干脆都用统一的hello.com/xxx,让服务端记住用户在首页的选择然后根据这个信息来判断?

 

这些方案各有利弊。我最推荐子域名区隔方案(hangzhou.hello.com/xxx),因为它在代码容错方面有突出的优势。

 

要解决的问题

对开发人员来说,多子站系统面临的问题是:

1.       处理用户请求如何判断用户当前所在的子站?是否要通过URL里的子站标识来判断?

2.       如果判断机制依赖URL,那么站内的所有链接应该都要带上子站标识,这样实现起来会不会很麻烦

 

对产品经理来说, URL的长度、结构对用户体验也会有些影响。

 

不同的方案解决这些问题的能力也不同。

 

方案一:统一URL,通过服务端session对象区分站点

方案:用户在首页或者合适的地方显式地选择子站然后后台将子站标识存入session,后续的所有访问都依赖于session里的子站标识,URL全站统一

 

这种方案的缺点很大

1.       大多数系统中,业务逻辑相关代码可以直接操纵session, 一旦代码写错或者漏写,很容易出现问题(尤其是新人接手时)。典型的例子:

a)         可能出现空白的页面区块、以及空指针错误。原因:在用户登出后,整个session对象被消灭,导致子站标识从session里也找不到。

b)         杭州站某条导购信息的页面中可能出现北京站的logo 原因:代码里只知道展现导购信息,忘了更新session对象中的站点标识;当用户离开北京站来到杭州站时,就有可能出错。

2.       所有请求都是有状态的请求。

a)         URL无法代表完整的请求 在杭州站搜索完后把链接发给外地的朋友,朋友打开后可能看到的是北京的搜索结果

b)         某个请求一旦弄错了Session,后续请求都会弄错。

 

这种方案也有些好处

1.       统一、简洁的URL,美观大方

2.       开发人员写站内链接时不必带上子站标识。直接写hello.com/xxx即可,不必写hello.com/hangzhou/xxx . (后文可以看出,这个很重要)

 

方案二:在URL PathURL 参数中携带子站标识

方案: 每个请求都是这种风格:hello.com/hangzhou/xxx hello.com/xxx?site=hangzhou ; 后端服务器通过一个拦截器(如struts2中的interceptor)拦截所有请求,根据URL中的子站标识确定当前子站,并把它作为attribute存到当前request对象中 (request.setAttribute(“site”, “hangzhou”)

 

优点:不依赖session,不存在前一种方案说的各种问题

 

缺点:

1.       每个请求都要拦截,可能会有性能浪费。在一般情况下,这种性能损失都很小或者可以通过技术手段来规避。

2.       URL冗长丑陋。尤其是xxx?site=hangzhou这种,有点影响心情。

3.       (致命的) 所有站内链接都必须带上站点标识

a)         你的jsp/Freemarker/velocity总是要加上一串:/yyy?site=${site}, 按我的经验和观察,这很容易遗漏(尤其是项目紧的时候),导致站点老是出现小毛病。

b)         另一种解决方案是使用自定义的jsp/freemarket/velocity View Tag, <@mylink href=”/yyy”/>.  这样做的后果也很严重:它导致前端工程师在设计页面时无法直接使用原生的html <a/>标签,这对前后端分工有很大影响。

方案三:使用子域名来区隔站点

方案:使用hangzhou.hello.com/xxx这种URL

优点:

1.       解决了前一个方案中关于站内链接的问题。站内链接使用相对链接,如果当前站点是北京站,则用户点击/xxx时会浏览器会自然地进入beijing.hello.com/xxx,保持了一致性。

2.       URL的美观度上也比前一个方案好一些,而且用户可以直接记住子域名,不太专业地说,这对培养用户的子站意识也有好处。

 

总结

以上三种方案中,子域名方案是最值得推荐的,在最近的一个项目中我使用了这种方案并且效果不错。

 

不管你用那种方案,都必须注意一点:子站区隔机制最好要单一、并且必须集中在单一的API接口中供业务代码调用。我曾经经历过这样一个系统:既可以通过URL判断子站、又可以通过域名判断、又把子站标识放进了session,而且分别有一个API可以让你随意调用。在这种机制下,程序员非常非常容易犯错误,对机制进行微调时也经常有遗漏,因为这个引起的bug可以说是家常便饭……

你可能感兴趣的:(url)