利用同構JavaScript輕鬆解析URL

douxingxiang發表於2015-06-08

大部分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解析、日期處理、貨幣格式等。

考慮到客戶端和伺服器上不同型別的邏輯,我不確定完全的同構應用是否具有實用性或者可行。但是,環境無關的庫可以消除對相同功能編寫兩份程式碼的痛苦。

相關文章