天天看點

如何用 JavaScript 來解析 URL

如何用 JavaScript 來解析 URL

英文 | https://dmitripavlutin.com/parse-url-javascript/

統一資源定位符,縮寫為URL,是對網絡資源(網頁、圖像、檔案)的引用。URL指定資源位置和檢索資源的機制(http、ftp、mailto)。

舉個例子,這裡是這篇文章的 URL 位址:

https://dmitripavlutin.com/parse-url-JavaScript      

很多時候你需要擷取到一段 URL 的某個組成部分。它們可能是 hostname(例如 dmitripavlutin.com),或者 pathname(例如 /parse-url-JavaScript)。

一個友善的用于擷取 URL 組成部分的辦法是通過 URL() 構造函數。

在這篇文章中,我将給大家展示一段 URL 的結構,以及它的主要組成部分。

接着,我會告訴你如何使用 URL() 構造函數來輕松擷取 URL 的組成部分,比如 hostname,pathname,query 或者 hash。

1、URL 結構

一圖勝千言。不需要過多的文字描述,通過下面的圖檔你就可以了解一段 URL 的各個組成部分:

如何用 JavaScript 來解析 URL

2、URL() 構造函數

URL() 構造函數允許我們用它來解析一段 URL:

const url = new URL(relativeOrAbsolute [, absoluteBase]);      

參數 relativeOrAbsolute 既可以是絕對路徑,也可以是相對路徑。如果第一個參數是相對路徑的話,那麼第二個參數 absoluteBase 則必傳,且必須為第一個參數的絕對路徑。

舉個例子,讓我們用一個絕對路徑的 URL 來初始化 URL() 函數:

const url = new URL('http://example.com/path/index.html');
url.href; // => 'http://example.com/path/index.html'      

或者我們可以使用相對路徑和絕對路徑:

const url = new URL('/path/index.html', 'http://example.com');
url.href; // => 'http://example.com/path/index.html'      

URL() 執行個體中的 href 屬性傳回了完整的 URL 字元串。

在建立了 URL() 的執行個體以後,你可以用它來通路前文圖檔中的任意 URL 組成部分。作為參考,下面是 URL() 執行個體的接口清單:

interface URL {
  href:     USVString;
  protocol: USVString;
  username: USVString;
  password: USVString;
  host:     USVString;
  hostname: USVString;
  port:     USVString;
  pathname: USVString;
  search:   USVString;
  hash:     USVString;


  readonly origin: USVString;
  readonly searchParams: URLSearchParams;


  tojsON(): USVString;
}      

上述的 USVString 參數在 JavaScript 中會映射成字元串。

3、Query 字元串

url.search 可以擷取到 URL 當中 ? 後面的 query 字元串:

const url = new URL(
  'http://example.com/path/index.html?message=hello&who=world'
);


url.search; // => '?message=hello&who=world'      

如果 query 參數不存在,url.search 預設會傳回一個空字元串 '':

const url1 = new URL('http://example.com/path/index.html');
const url2 = new URL('http://example.com/path/index.html?');


url1.search; // => ''
url2.search; // => ''      

3.1 、解析 query 字元串

相比于獲得原生的 query 字元串,更實用的場景是擷取到具體的 query 參數。

擷取具體 query 參數的一個簡單的方法是利用 url.searchParams 屬性。這個屬性是 URLSearchParams 的執行個體。

URLSearchParams 對象提供了許多用于擷取 query 參數的方法,如get(param),has(param)等。

下面來看個例子:

const url = new URL(
  'http://example.com/path/index.html?message=hello&who=world'
);


url.searchParams.get('message'); // => 'hello'
url.searchParams.get('missing'); // => null      

url.searchParams.get('message') 傳回了 message 這個 query 參數的值——hello。

如果使用 url.searchParams.get('missing') 來擷取一個不存在的參數,則得到一個 null。

4、hostname

url.hostname 屬性傳回一段 URL 的 hostname 部分:

const url = new URL('http://example.com/path/index.html');
url.hostname; // => 'example.com'      

5、pathname

url. pathname 屬性傳回一段 URL 的 pathname 部分:

const url = new URL('http://example.com/path/index.html?param=value');
url.pathname; // => '/path/index.html'      

如果這段 URL 不含 path,則該屬性傳回一個斜杠 /:

const url = new URL('http://example.com/');
url.pathname; // => '/'      

6、hash

最後,我們可以通過 url.hash 屬性來擷取 URL 中的 hash 值:

const url = new URL('http://example.com/path/index.html#bottom');
url.hash; // => '#bottom'      

當 URL 中的 hash 不存在時,url.hash 屬性會傳回一個空字元串 '':

const url = new URL('http://example.com/path/index.html');
url.hash; // => ''      

7、URL 校驗

當使用 new URL() 構造函數來建立執行個體的時候,作為一種副作用,它同時也會對 URL 進行校驗。如果 URL 不合法,則會抛出一個 TypeError。

舉個例子,http ://example.com 是一段非法 URL,因為它在 http 後面多寫了一個空格。

讓我們用這個非法 URL 來初始化 URL() 構造函數:

try {
  const url = new URL('http ://example.com');
} catch (error) {
  error; // => TypeError, "Failed to construct URL: Invalid URL"
}      

因為 http ://example.com 是一段非法 URL,跟我們想的一樣,new URL() 抛出了一個 TypeError。

8、修改 URL

除了擷取 URL 的組成部分以外,像 search,hostname,pathname 和 hash 這些屬性都是可寫的——這也意味着你可以修改 URL。

舉個例子,讓我們把一段 URL 從 red.com 修改成 blue.io:

const url = new URL('http://red.com/path/index.html');


url.href; // => 'http://red.com/path/index.html'


url.hostname = 'blue.io';


url.href; // => 'http://blue.io/path/index.html'      

注意,在 URL() 執行個體中隻有 origin 和 searchParams 屬性是隻讀的,其他所有的屬性都是可寫的,并且會修改原來的 URL。

9、總結

URL() 構造函數是 JavaScript 中的一個能夠很友善地用于解析(或者校驗)URL 的工具。

new URL(relativeOrAbsolute [, absoluteBase]) 中的第一個參數接收 URL 的絕對路徑或者相對路徑。當第一個參數是相對路徑時,第二個參數必傳且必須為第一個參數的基路徑。

在建立 URL() 的執行個體以後,你就能很輕易地獲得 URL 當中的大部分組成部分了,比如:

  • url.search 擷取原生的 query 字元串
  • url.searchParams 通過 URLSearchParams 的執行個體去擷取具體的 query 參數
  • url.hostname擷取 hostname
  • url.pathname 擷取 pathname
  • url.hash 擷取 hash 值