利用同构JavaScript轻松解析URL

546 查看

大部分web应用都需要解析URL,无论是提取域名、实现REST API,还是查找图片路径。一个典型的URL路径如下图所示:

你可以使用正则表达式把URL字符串拆分为连续的部分,但是这有点复杂而且没必要…

服务端URL解析

Node.js(及其分支,比如io.js)提供了URL API

你可以从上面的片段中看出,parse()方法返回一个包含所需数据(比如协议、主机名、端口等)的对象。

客户端URL解析

浏览器端没有对应的API。但是如果浏览器有件事做得好的话,那就是URL解析和DOM中的链接实现了类似的Location接口,例如:

如果我们把URL字符串放到内存的锚点元素(a)中,就可以不依赖正则表达式来解析,例如:

同构URL解析

Aurelio最近讨论了同构JavaScript应用。实质上,它是将渐进增强(progressive enhancement)推到了极致:应用可以在客户端或服务器上快乐地运行了。使用现代浏览器的用户可以使用单页应用。老式浏览器和搜索引擎爬虫将会看到服务端渲染的应用。理论上,应用可以根据设备的速度和带宽能力来实现不同等级的客户端/服务器处理。

同构JavaScript(Isomorphic JavaScript)已经被讨论过很多年,但是太复杂。很少项目能够在实现共享视图基础之上更进一步,而且标准渐进增强不起作用的情况也不多(如果没有更好地考虑到,大部分没有客户端JavaScript的“同构”框架都会失效)。意思是,可以实现环境无关的宏观库来试探性地迈出同构概念的第一步。

我们考虑下怎样在lib.js文件中编写一个URL解析库。首先,我们检测代码运行的位置:

这个方法不是特别健壮,因为你可能在客户端定义了module.exports函数,但是我不知道其他更好的方式(欢迎提供建议)。其他开发者的类似方法是检测window对象是否存在:

现在我们使用URLparse函数完成lib.js代码:

我在代码中使用isNode变量作澄清。但是,你可以直接把检测代码放到代码片段的最后一个圆括号内。

服务器端,URLparse导出为Common.JS模块。这样使用:

客户端,URLparse作为全局lib对象的一个方法:

除了库中包含的方法,客户端和服务端API都是相同的。

要承认的是,这是一个简单例子,URLparse在不同客户端和服务端上运行(大部分)不同代码。但是我们实现了一致性的API,可以说明JavaScript代码可以运行在任意位置。我们可以扩展这个库来提供更多客户端/服务器实用函数,比如字段验证、cookie解析、日期处理、货币格式等。

考虑到客户端和服务器上不同类型的逻辑,我不确定完全的同构应用是否具有实用性或者可行。但是,环境无关的库可以消除对相同功能编写两份代码的痛苦。