歡迎光臨
每天分享高質量文章

利用同構JavaScript輕鬆解析URL

大部分web應用都需要解析URL,無論是提取域名、實現REST API,還是查詢圖片路徑。一個典型的URL路徑如下圖所示:

你可以使用正則運算式把URL字串拆分為連續的部分,但是這有點複雜而且沒必要…

服務端URL解析

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

// Server-side JavaScript

var urlapi = require(‘url’),

url = urlapi.parse(‘http://site.com:81/path/page?a=1&b=2#hash’);

console.log(

url.href + ‘n’ +

// the full URL

url.protocol + ‘n’ +

// http:

url.hostname + ‘n’ +

// site.com

url.port + ‘n’ +

// 81

url.pathname + ‘n’ +

// /path/page

url.search + ‘n’ +

// ?a=1&b=2

url.hash

// #hash

);

你可以從上面的片段中看出,parse()方法傳回一個包含所需資料(比如協議、主機名、埠等)的物件。

客戶端URL解析

瀏覽器端沒有對應的API。但是如果瀏覽器有件事做得好的話,那就是URL解析和DOM中的連結實現了類似的Location介面,例如:

// Client-side JavaScript

// find the first link in the DOM

var url = document.getElementsByTagName(‘a’)[0];

console.log(

url.href + ‘n’ +

// the full URL

url.protocol + ‘n’ +

// http:

url.hostname + ‘n’ +

// site.com

url.port + ‘n’ +

// 81

url.pathname + ‘n’ +

// /path/page

url.search + ‘n’ +

// ?a=1&b=2

url.hash

// #hash

);

如果我們把URL字串放到記憶體的錨點元素(a)中,就可以不依賴正則運算式來解析,例如:

// Client-side JavaScript

// create dummy link

var url = document.createElement(‘a’);

url.href = ‘http://site.com:81/path/page?a=1&b=2#hash’;

console.log(url.hostname);

// site.com

同構URL解析

Aurelio最近討論了同構JavaScript應用。實質上,它是將漸進增強(progressive enhancement)推到了極致:應用可以在客戶端或伺服器上快樂地運行了。使用現代瀏覽器的使用者可以使用單頁應用。老式瀏覽器和搜尋引擎爬蟲將會看到服務端渲染的應用。理論上,應用可以根據裝置的速度和頻寬能力來實現不同等級的客戶端/伺服器處理。

同構JavaScript(Isomorphic JavaScript)已經被討論過很多年,但是太複雜。很少專案能夠在實現共享檢視基礎之上更進一步,而且標準漸進增強不起作用的情況也不多(如果沒有更好地考慮到,大部分沒有客戶端JavaScript的“同構”框架都會失效)。意思是,可以實現環境無關的宏觀庫來試探性地邁出同構概念的第一步。

我們考慮下怎樣在lib.js檔案中編寫一個URL解析庫。首先,我們檢測程式碼執行的位置:

// running on Node.js?

var isNode = ( typeof module === ‘object’ && module.exports);

這個方法不是特別健壯,因為你可能在客戶端定義了module.exports函式,但是我不知道其他更好的方式(歡迎提供建議)。其他開發者的類似方法是檢測window物件是否存在:

// running on Node.js?

var isNode = typeof window === ‘undefined’;

現在我們使用URLparse函式完成lib.js程式碼:

// lib.js library functions

// running on Node.js?

var isNode = ( typeof module === ‘object’ && module.exports);

( function (lib) {

“use strict” ;

// require Node URL API

var url = (isNode ? require(‘url’) : null);

// parse URL

lib.URLparse = function(str) {

if (isNode) {

return url.parse(str);

}

else {

url = document.createElement(‘a’);

url.href = str;

return url;

}

}

})(isNode ? module.exports : this.lib = {});

我在程式碼中使用isNode變數作澄清。但是,你可以直接把檢測程式碼放到程式碼片段的最後一個圓括號內。

伺服器端,URLparse匯出為Common.JS模組。這樣使用:

// include lib.js module

var lib = require(‘./lib.js’);

var url = lib.URLparse(‘http://site.com:81/path/page?a=1&b=2#hash’);

console.log(

url.href + ‘n’ +

// the full URL

url.protocol + ‘n’ +

// http:

url.hostname + ‘n’ +

// site.com

url.port + ‘n’ +

// 81

url.pathname + ‘n’ +

// /path/page

url.search + ‘n’ +

// ?a=1&b=2

url.hash

// #hash

);

客戶端,URLparse作為全域性lib物件的一個方法:


贊(0)

分享創造快樂