精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何使用 JavaScript 解析 URL?

開(kāi)發(fā) 前端
URL 是 Uniform Resource Locator 的縮寫(xiě),即統(tǒng)一資源定位符。URL 就是一個(gè)給定的獨(dú)特資源在 Web 上的地址。

如果你從事 Web 前端開(kāi)發(fā)有一段時(shí)間了,相信一定會(huì)遇到需要使用 JavaScript 解析 URL 地址信息的時(shí)候。本文就介紹一下如何使用 JavaScript 解析 URL。

[[417013]]

在《認(rèn)識(shí) URI 與 URL》一文中具體介紹了 URI 的格式,要使用 JavaScript 解析 URL 信息,必須先了解 URL 格式是怎樣的,讓我們先來(lái)回顧一下吧。

URL 格式

 

 

完整的 URL 信息包括以下幾點(diǎn):

  • 協(xié)議(protocol):采用的協(xié)議方案;
  • 登錄信息(username & password):(可選項(xiàng))指定用戶(hù)名和密碼,用來(lái)從服務(wù)器獲取資源時(shí)的認(rèn)證信息;
  • 服務(wù)器地址(hostname):待訪問(wèn)的服務(wù)器地址。可以是域名形式也可以是 IP 地址;
  • 服務(wù)器端口號(hào)(port):;指定服務(wù)器連接網(wǎng)路的端口號(hào);
  • 帶層次的文件路徑(pathname):指定服務(wù)器上的文件路徑來(lái)定位特指的資源;
  • 查詢(xún)字符串(search):(可選項(xiàng))查詢(xún)字符串參數(shù);
  • 片段標(biāo)識(shí)符(hash):(可選項(xiàng))用來(lái)標(biāo)記已獲取資源中的子資源;

解析 URL

在回顧了 URL 都包括哪些信息后,現(xiàn)在就先按照前文的 URL 格式人工解析一下 URL 的信息。以本文地址地址為例:

 

  1. http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/ 

按照 URL 的格式規(guī)范,本文的 URL 地址解析后的信息應(yīng)該如下:

  • protocol: http;
  • hostname: www.yaohaixiao.com;
  • pathname: /blog/how-to-parse-url-with-javascript/;

可以看到,本文地址的 URL 解析后的信息并沒(méi)有前文提到的完整 URL 信息中那么多。這是因?yàn)?URL 信息中有幾項(xiàng)信息是可選項(xiàng)信息,本文的示例 URL 地址中都是沒(méi)有值的。

在通過(guò)人工分析的方式分析了一遍,現(xiàn)在就要開(kāi)始使用 JavaScript 編程解析 URL 信息了。當(dāng)然,解析 URL 信息的方法很多,本文主要介紹兩種解析方法:正則表達(dá)式解析 和 URL 構(gòu)造函數(shù)解析。

正則表達(dá)式解析

使用 JavaScript 中的正則表達(dá)解析 URL 信息應(yīng)該最常見(jiàn)的方法了,當(dāng)然這需要具備一定的 JavaScript 正則表達(dá)式相關(guān)的知識(shí)。而使用正則表達(dá)式分析 URL 地址其實(shí)也并不復(fù)雜。

按照前文圖片中的 URL 信息的結(jié)構(gòu),使用括號(hào)“()”分組表達(dá)符對(duì) URL 中對(duì)應(yīng)的信息進(jìn)行分組,正則表達(dá)式的偽代碼大致如下:

 

  1. /^((protocol):)?\/\/((username):(password)@)?(hostname)(:(port))?(pathname)(\\?(search))?(#(hash))?/ 

可以看到,正則表達(dá)式也分了 7 組:

  • protocol – 協(xié)議分組:((protocol):)?,最外層的 ()? 中,? 表示數(shù)量為 0 或 1 個(gè),即表示協(xié)議名稱(chēng)是可選的;
  • auth – 授權(quán)信息分組:((username):(password)@)?,與協(xié)議分組一樣,整個(gè)授權(quán)分組也是可選的。其中又包含 username 子分組和 password 子分組;
  • hostname – 服務(wù)器地址分組:(hostname),表示 hostname 信息是必選的;
  • port – 端口分組:(:(port))?,表示端口號(hào)是可選的;
  • pathname – 帶層次的文件路徑分組:(pathname),表示文件路徑是必選的;
  • search – 查詢(xún)字符串分組:(\\?(search))?,表示查詢(xún)字符串是可選的;
  • hash – 片段標(biāo)識(shí)符分組:(#(hash))?,表示片段標(biāo)識(shí)符分組也是可選的;

完成了大的分組后,接下來(lái)要處理的問(wèn)題就是相對(duì)比較容易了,就是用真實(shí)的正則表達(dá)式將使用英文字母的偽代碼內(nèi)容替換掉。對(duì)應(yīng)完整的 JavaScript 的正則表達(dá)式代碼如下圖:

 

如何使用 JavaScript 解析 URL?

 

可以看到,圖中藍(lán)色文字標(biāo)識(shí)的是偽代碼中對(duì)應(yīng)的 7 個(gè)分組,而灰色文字標(biāo)識(shí)的是最終需要獲取的 URL 對(duì)應(yīng)的信息。下面就詳細(xì)介紹一下各個(gè)分組的正則表達(dá)式的含義。

1. protocol(協(xié)議分組)

 

  1. // ((protocol):)? 
  2. (([^:/?#]+):)? 

 

([^:/?#]+),匹配協(xié)議名稱(chēng)(子分組),具體的含義如下:

  • [^],表示除了“^”符號(hào)后的字符以外的所有字符。 [^:/?#] 就表示除了”:”(冒號(hào))、”/”(反斜杠)、“?”(問(wèn)號(hào))和“#”(井號(hào))以外的所有字符。也就是是說(shuō),協(xié)議名稱(chēng)可是除了以上符號(hào)以外的所有字符都可以。我這個(gè)匹配比較寬泛,通常協(xié)議名稱(chēng)是字母,所以也可以寫(xiě)作([a-zA-Z])。除非確定邀請(qǐng)非常高的匹配精度,可以適當(dāng)寫(xiě)寬泛一些;
  • []+,中括號(hào)后的 + 表示數(shù)量為 1~n 個(gè),所以 ([^:/?#]+) 整個(gè)的意思是協(xié)議名稱(chēng)匹配為除了”:”(冒號(hào))、“?”(問(wèn)號(hào))和“#”(井號(hào))以外的所有字符字符都可以,并且長(zhǎng)度要求是1個(gè)以上;

(([^:/?#]+):)?,匹配協(xié)議名稱(chēng)加“:”格式,例如:http: 。當(dāng)然,在介紹分組偽代碼的時(shí)候,介紹過(guò)了,()? 括號(hào)后的 ? 標(biāo)識(shí)整個(gè)協(xié)議分組是可選的。而之所以將協(xié)議分組作為可選的,是應(yīng)為實(shí)際的應(yīng)用中:

//www.yaohaixiao.com/favicon.ico,這種不帶協(xié)議名稱(chēng)的 URL 地址也是允許的。

因此,(([^:/?#]+):)? 這段表達(dá)式將匹配 2 組數(shù)據(jù):http: 和 http,前者是大分組 ()? 匹配的信息,后者則是子分組 ([^:/?#]+) 匹配的信息,也是真正希望解析的 URL 協(xié)議信息。不過(guò)由于整個(gè)協(xié)議分組是可選的,因此協(xié)議分組的兩個(gè)分組也可能都匹配不到數(shù)據(jù)。

2. auth(授權(quán)信息分組)

 

  1. // ((username):(password)@)? 
  2. (([^/?#]+):(.+)@)? 

 

([^/?#]+),匹配用戶(hù)名,由于規(guī)則和匹配協(xié)議名稱(chēng)一樣,在此就不重復(fù)了。

(.+),匹配密碼。具體含義如下:

  • “.”,表示任何字符。因?yàn)槊艽a由于考慮安全因數(shù),一般都希望密碼是包含字符(而且包含大小寫(xiě)),數(shù)組和特殊字符的組合。所以直接不做任何限制,允許密碼包含任意字符。
  • “+”,表示數(shù)量為1個(gè)或者多個(gè),即密碼不能為空。

(([^/?#]+):(.+)@)?,匹配完整的授權(quán)信息。匹配的數(shù)據(jù)如:yao:Yao1!@。與授權(quán)信息一樣,最外層的()?表示授權(quán)信息也是可選的。

因此,(([^/?#]+):(.+)@)? 整個(gè)會(huì)匹配 3 組數(shù)據(jù):完整的用戶(hù)授權(quán)分組信息、用戶(hù)名以及密碼。由于整個(gè)協(xié)議分組是可選的,因此授權(quán)分組的 3 組信息也可能都匹配不到數(shù)據(jù)。

3. hostname(服務(wù)器地址分組)

 

  1. // (hostname) 
  2. ([^/?#:]*) 

 

([^/?#:]*),匹配服務(wù)器地址信息。和協(xié)議分組的表達(dá)式一樣,使用了比較寬松的匹配邏輯。

4. port(端口分組)

 

  1. // (:(port))? 
  2. (:(\d+))? 

 

(\d+),匹配端口號(hào)信息。端口號(hào)只能是數(shù)字類(lèi)型的數(shù)據(jù),對(duì)端口號(hào)長(zhǎng)度的要求是至少有一個(gè)。對(duì)端口號(hào)的長(zhǎng)途匹配也沒(méi)有使用太嚴(yán)苛的長(zhǎng)度要求。雖然通常端口號(hào)的長(zhǎng)度一般是 2 位數(shù)字起,但還是建議遵循之前提到的建議,如果不是有具體的精度要求,表達(dá)式都可以使用寬泛一些的匹配規(guī)則。

(:(\d+))?,匹配完整的端口號(hào)分組信息。匹配的格式如:“:80”。

同樣的,整個(gè)端口號(hào)分組匹配的表達(dá)式也是可以匹配 2 組數(shù)據(jù)::80 和 80。當(dāng)然,端口號(hào)分組也是可選的,很大可能配備不到信息。

5. pathname(帶層次的文件路徑分組)

 

  1. // (pathname) 
  2.  
  3. ([^?#]*) 

 

([^?#]*),匹配帶層次的文件路徑信息。具體的含義是:

  • [^?#],除了“?”(問(wèn)號(hào))和“#”(井號(hào))以外的所有字符都可以作為路徑信息。
  • []*,表示字符長(zhǎng)度可以是任意長(zhǎng)度。因?yàn)?URL 地址可以是這樣的:http://www.yaohaixiao.com。

雖然沒(méi)有使用“()?”的形式表示路徑為可選的,但用于路徑的長(zhǎng)度可以為 0,其實(shí)路徑也是可選的,也有可能匹配不到數(shù)據(jù)。

6. search(查詢(xún)字符串分組)

 

  1. // (\\?(search))? 
  2.  
  3. (\\?([^#]*))? 

 

([^#]*),匹配查詢(xún)字符串信息。除了“#”(井號(hào))以外的所有字符都可以作為查詢(xún)字符串信息。[]* 表示可選,因?yàn)槁窂剑篽ttp://www.yaohxiao.com? 也是允許的。

(\\?([^#]*))?,匹配查詢(xún)字符串的分組信息。匹配的格式如:?id=23。當(dāng)然也是可選的。

整個(gè)查詢(xún)字符串分組的表達(dá)式(\\?([^#]*))? ,也是可以匹配出 2 組數(shù)據(jù)。而因?yàn)檎麄€(gè)分組是可選的,所以查詢(xún)字符串的分組匹配也很可能匹配不到數(shù)據(jù)。

7. hash(片段標(biāo)識(shí)符分組)

 

  1. // (#(hash))? 
  2. (#(.*))? 

 

(.*),匹配片段標(biāo)識(shí)。“.”表示任意字符,“*”表示任意長(zhǎng)度。即片段表示可以是任意字符,且長(zhǎng)度為任意長(zhǎng)度的。

(#(.*))?,匹配判斷標(biāo)識(shí)分組。匹配的格式如:#1234。看到()?,就知道片段標(biāo)識(shí)符分組是可選的。

整個(gè)片段標(biāo)識(shí)符分組的表達(dá)式(#(.*))? ,也可以匹配出 2 組數(shù)據(jù)。當(dāng)然,也可能什么也匹配不上。

介紹完所有的分組表達(dá)式,最后來(lái)統(tǒng)計(jì)一下最多一共可以匹配多少組數(shù)據(jù):2 + 3 + 1 + 2 + 1 + 2 + 2 + 1 = 14。其中,最后一個(gè)加1,是匹配的整個(gè) URL 地址。

驗(yàn)證一下使用正則表達(dá)式對(duì)本文 URL 地址的匹配信息:

 

  1. const URL = 'http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/' 
  2. const pattern = /^(([^:/?#]+):)?\/\/(([^/?#]+):(.+)@)?([^/?#:]*)(:(\d+))?([^?#]*)(\\?([^#]*))?(#(.*))?/ 
  3. const matches = URL.match(pattern) 
  4. console.log(matches) 

 

輸出的結(jié)果為:

 

  1. 0: "http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/" 
  2. 1: "http:" 
  3. 2: "http" 
  4. 3: undefined 
  5. 4: undefined 
  6. 5: undefined 
  7. 6: "www.yaohaixiao.com" 
  8. 7: undefined 
  9. 8: undefined 
  10. 9: "/blog/how-to-parse-url-with-javascript/" 
  11. 10: undefined 
  12. 11: undefined 
  13. 12: undefined 
  14. 13: undefined 
  15. groups: undefined 
  16. index: 0 
  17. input: "http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/" 

 

正如之前人工分析的一樣,使用 match() 方法匹配了 14 個(gè)結(jié)果。由于示例 URL 地址中很多可選的信息都是沒(méi)有的,所以匹配結(jié)果為 undefined。但這個(gè)結(jié)果并不是那么一目了然,讓我們看看完整的 parseURL() 方法。

完整的 parseURL() 方法

完整的 parseURL() 方法的如下:

 

  1. /** 
  2.  * 分析 url 地址,將解析的結(jié)果作為對(duì)象返回,返回屬性有: 
  3.  * 1. href - 完整 URL 地址 
  4.  * 2. protocol - 協(xié)議 
  5.  * 3. username - 用戶(hù)名 
  6.  * 4. password - 密碼 
  7.  * 5. host - 域名地址 
  8.  * 6. hostname - 域名名稱(chēng) 
  9.  * 7. port - 端口號(hào) 
  10.  * 8. path - 路徑 
  11.  * 9. pathname - 路徑名 
  12.  * 10. search - 查詢(xún)參數(shù) 
  13.  * 11. hash - 哈希值 
  14.  * 12. origin 
  15.  * 13. searchParams 
  16.  * ==================================================== 
  17.  * @param {String} url - URL地址 
  18.  * @param {String} [base] - 基準(zhǔn) URL 地址 
  19.  * @returns {Object} 
  20.  */ 
  21. const parseURLWithRegExp = (url = location.href, base) => { 
  22.   const pattern = /^(([^:/?#]+):)?\/\/(([^/?#]+):(.+)@)?([^/?#:]*)(:(\d+))?([^?#]*)(\\?([^#]*))?(#(.*))?/ 
  23.   const getURLSearchParams = (url) => { 
  24.     return (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce((a, v) => { 
  25.       return ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a) 
  26.     }, {}) 
  27.   } 
  28.   let matches, 
  29.     hostname, 
  30.     port, 
  31.     pathname, 
  32.     search, 
  33.     searchParams 
  34.  
  35.   // url 是為度路徑時(shí),忽略 base 
  36.   if (/^(([^:/?#]+):)/.test(url)) { 
  37.     base = '' 
  38.   } 
  39.  
  40.   // 設(shè)置了基準(zhǔn) URL 
  41.   if (base) { 
  42.     // 移除 base 最后的斜杠 ‘/’ 
  43.     if (/[/]$/.test(base)) { 
  44.       base = base.replace(/[/]$/, ''
  45.     } 
  46.  
  47.     // 確保 url 開(kāi)始有斜杠 
  48.     if (!/^[/]/.test(url)) { 
  49.       url = '/' + url 
  50.     } 
  51.  
  52.     // 保證 URL 地址拼接后是一個(gè)正確的格式 
  53.     url = base + url 
  54.   } 
  55.  
  56.   matches = url.match(pattern) 
  57.   hostname = matches[6] 
  58.   port = matches[8] || '' 
  59.   pathname = matches[11] || '/' 
  60.   search = matches[10] || '' 
  61.   searchParams = (() => { 
  62.     const params = getURLSearchParams(url) 
  63.  
  64.     return { 
  65.       get (name) { 
  66.         return params[name] || '' 
  67.       } 
  68.     } 
  69.   })() 
  70.  
  71.   return { 
  72.     href: url, 
  73.     origin: (matches[1] ? matches[1] + '//' : '') + hostname, 
  74.     protocol: matches[2] || ''
  75.     username: matches[4] || ''
  76.     password: matches[5] || ''
  77.     hostname, 
  78.     port, 
  79.     host: hostname + port, 
  80.     pathname, 
  81.     search, 
  82.     path: pathname + search, 
  83.     hash: matches[13] || ''
  84.     searchParams 
  85.   } 

 

它返回一個(gè)對(duì)象,將正則表達(dá)式匹配的信息復(fù)制給具體的 URL 名稱(chēng)的屬性。看看使用 parseURL() 方法解析前面的 URL 地址的結(jié)果吧:

 

  1. const URL = 'http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/' 
  2. const result = parseURL(URL) 

 

解析后的結(jié)果:

 

  1.   hash: undefined, 
  2.   host: "www.yaohaixiao.com"
  3.   hostname: "www.yaohaixiao.com"
  4.   href: "http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/"
  5.   orgin: "http://www.yaohaixiao.com"
  6.   password: undefined, 
  7.   path: "/blog/how-to-parse-url-with-javascript/undefined"
  8.   pathname: undefined, 
  9.   port: undefined, 
  10.   protocol: "http"
  11.   search: undefined, 
  12.   username: undefined, 

 

現(xiàn)在解析后的結(jié)果是不是一目了然了?當(dāng)然,使用正則表達(dá)式解析 URL 信息肯定不止本文提到的這一種方式,也有比本文中更好,更嚴(yán)謹(jǐn)?shù)钠ヅ湟?guī)則,但本文中使用的匹配方式相對(duì)來(lái)說(shuō)應(yīng)該是比較易于容易理解和相對(duì)兼容性也比較好的一種處理方式。

URL 構(gòu)造函數(shù)解析

除了前文介紹的使用 JavaScript 中的正則表達(dá)式解析 URL 信息之外,還可以利用新的 URL 構(gòu)造函數(shù)來(lái)解析 URL 地址,并且解析起來(lái)更加簡(jiǎn)單。

URL() 構(gòu)造函數(shù)

URL() 構(gòu)造函數(shù)返回一個(gè)新創(chuàng)建的 URL 對(duì)象,表示由一組參數(shù)定義的 URL。如果給定的基本 URL 或生成的 URL 不是有效的 URL 鏈接,則會(huì)拋出一個(gè) TypeError。

語(yǔ)法如下:

 

  1. new URL(url [, base]); 
  • url:是一個(gè)表示絕對(duì)或相對(duì) URL 的 DOMString。如果url 是相對(duì) URL,則會(huì)將 base 用作基準(zhǔn) URL。如果 url 是絕對(duì)URL,則無(wú)論參數(shù)base是否存在,都將被忽略;
  • base:可選,是一個(gè)表示基準(zhǔn) URL 的 DOMString,在 url 是相對(duì) URL 時(shí),它才會(huì)起效。如果未指定,則默認(rèn)為 ”;

調(diào)用方法如下:

 

  1. // 直接使用絕對(duì) URL 地址方式調(diào)用 
  2. const url = new URL('http://example.com/path/index.html'); 
  3.  
  4. // 使用 path 加 base 地址參數(shù)的方式調(diào)用 
  5. const url = new URL('/path/index.html''http://example.com'); 

 

URL() 構(gòu)造函數(shù)的接口信息如下:

 

  1. interface URL { 
  2.   href:     USVString; 
  3.   protocol: USVString; 
  4.   username: USVString; 
  5.   password: USVString; 
  6.   host:     USVString; 
  7.   hostname: USVString; 
  8.   port:     USVString; 
  9.   pathname: USVString; 
  10.   search:   USVString; 
  11.   hash:     USVString; 
  12.    
  13.   // 只有 orgin 和 searchParams 是只讀,其余的屬性都是可修改的 
  14.   readonly origin: USVString; 
  15.   readonly searchParams: URLSearchParams; 
  16.  
  17.   toJSON(): USVString; 

 

所以每個(gè)使用 URL() 構(gòu)造函數(shù)創(chuàng)建的實(shí)例,都會(huì)返回完整 URL 信息了。例如:

 

  1. const url = new URL('http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/'); 

返回的數(shù)據(jù)為:

 

  1.   hash: ""
  2.   host: "www.yaohaixiao.com"
  3.   hostname: "www.yaohaixiao.com"
  4.   href: "http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/"
  5.   origin: "http://www.yaohaixiao.com"
  6.   password""
  7.   pathname: "/blog/how-to-parse-url-with-javascript/"
  8.   port: ""
  9.   protocol: "http:"
  10.   search: ""
  11.   searchParams: URLSearchParams {}, 
  12.   username: "" 

 

可以看到,使用 URL() 構(gòu)造函數(shù)返回的數(shù)據(jù)和前文使用正則表達(dá)式解析的數(shù)據(jù)基本一致,只是這里多了一個(gè) searchParams 對(duì)象。

searchParams 對(duì)象又是 URLSearchParams 對(duì)象的一個(gè)實(shí)例,用來(lái)獲取查詢(xún)字符串中的某個(gè)參數(shù)的值,用法如下:

 

  1. const url = new URL('http://www.yaohaixiao.com/blog/how-to-parse-url-with-javascript/?id=312'); 
  2. url.searchParams.get('id') // -> 123 

 

URL() 構(gòu)造函數(shù)的功能是不是很強(qiáng)大了。不知道 URL() 構(gòu)造函數(shù)瀏覽器支持的情況怎么樣?

URL() 構(gòu)造函數(shù)的瀏覽器兼容情況

 

如何使用 JavaScript 解析 URL?

 

在主流瀏覽器中,除了 IE 瀏覽器,其余的都基本支持了。基本上可以放心使用 URL() 構(gòu)造函數(shù)來(lái)解析 URL 信息。

使用 URL() 構(gòu)造函數(shù)來(lái)解析 URL 信息的完整代碼如下:

 

  1. /** 
  2.  * 分析 url 地址,將解析的結(jié)果作為對(duì)象返回,返回屬性有: 
  3.  * 1. href - 完整 URL 地址 
  4.  * 2. protocol - 協(xié)議 
  5.  * 3. username - 用戶(hù)名 
  6.  * 4. password - 密碼 
  7.  * 5. host - 域名地址 
  8.  * 6. hostname - 域名名稱(chēng) 
  9.  * 7. port - 端口號(hào) 
  10.  * 8. path - 路徑 
  11.  * 9. pathname - 路徑名 
  12.  * 10. search - 查詢(xún)參數(shù) 
  13.  * 11. hash - 哈希值 
  14.  * 12. origin 
  15.  * 13. searchParams 
  16.  * ==================================================== 
  17.  * @param {String} url - URL地址 
  18.  * @param {String} [base] - 基準(zhǔn) URL 地址 
  19.  * @returns {Object} 
  20.  */ 
  21. const parseURLWithURLConstructor = (url= location.href, base) => { 
  22.   const results = new URL(url, base) 
  23.   const protocol = results.protocol.replace(':'''
  24.  
  25.   return { 
  26.     href: url, 
  27.     origin: results.origin, 
  28.     protocol, 
  29.     username: results.username, 
  30.     password: results.password
  31.     hostname: results.hostname, 
  32.     port: results.port, 
  33.     host: results.host, 
  34.     pathname: results.pathname, 
  35.     search: results.search, 
  36.     path: results.pathname + results.search, 
  37.     hash: results.hash, 
  38.     searchParams: results.searchParams 
  39.   } 

 

正則表達(dá)式解析 VS URL 構(gòu)造函數(shù)解析

對(duì)兩種解析 URL 信息的方法進(jìn)行比較,很明顯使用 URL() 構(gòu)造函數(shù)解析的方法操作更加簡(jiǎn)單,并且提供更多的功能。但與正則表達(dá)式解析方法比較,可能唯一不足的就是在 IE 瀏覽器中無(wú)法使用。

其實(shí),只要稍微調(diào)整一下,就可以將兩種方法結(jié)合起來(lái),在支持 URL() 構(gòu)造函數(shù)的瀏覽器中使用構(gòu)造函數(shù),不知支持的時(shí)候則使用正則表達(dá)式解析:

 

  1. /** 
  2.  * 分析 url 地址,將解析的結(jié)果作為對(duì)象返回,返回屬性有: 
  3.  * 1. href - 完整 URL 地址 
  4.  * 2. protocol - 協(xié)議 
  5.  * 3. username - 用戶(hù)名 
  6.  * 4. password - 密碼 
  7.  * 5. host - 域名地址 
  8.  * 6. hostname - 域名名稱(chēng) 
  9.  * 7. port - 端口號(hào) 
  10.  * 8. path - 路徑 
  11.  * 9. pathname - 路徑名 
  12.  * 10. search - 查詢(xún)參數(shù) 
  13.  * 11. hash - 哈希值 
  14.  * 12. origin 
  15.  * ==================================================== 
  16.  * @param {String} url - URL地址 
  17.  * @param {String} [base] - 基準(zhǔn) URL 地址 
  18.  * @returns {Object} 
  19.  */ 
  20. const parseURL = (url = location.href, base) => { 
  21.   const getURLSearchParams = (url) => { 
  22.     return (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce((a, v) => { 
  23.       return ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a) 
  24.     }, {}) 
  25.   } 
  26.  
  27.   const parseURLWithRegExp = (url) => { 
  28.     const pattern = /^(([^:/?#]+):)?\/\/(([^/?#]+):(.+)@)?([^/?#:]*)(:(\d+))?([^?#]*)(\\?([^#]*))?(#(.*))?/, 
  29.       matches = url.match(pattern), 
  30.       hostname = matches[6], 
  31.       port = matches[8] || ''
  32.       pathname = matches[11] || '/'
  33.       search = matches[10] || ''
  34.       searchParams = (() => { 
  35.         const params = getURLSearchParams(url) 
  36.  
  37.         return { 
  38.           get (name) { 
  39.             return params[name] || '' 
  40.           } 
  41.         } 
  42.       })() 
  43.  
  44.     return { 
  45.       href: url, 
  46.       origin: (matches[1] ? matches[1] + '//' : '') + hostname, 
  47.       protocol: matches[2] || ''
  48.       username: matches[4] || ''
  49.       password: matches[5] || ''
  50.       hostname, 
  51.       port, 
  52.       host: hostname + port, 
  53.       pathname, 
  54.       search, 
  55.       path: pathname + search, 
  56.       hash: matches[13] || ''
  57.       searchParams 
  58.     } 
  59.   } 
  60.  
  61.   const parseURLWithURLConstructor = (url) => { 
  62.     const results = new URL(url) 
  63.     const protocol = results.protocol.replace(':'''
  64.  
  65.     return { 
  66.       href: url, 
  67.       origin: results.origin, 
  68.       protocol, 
  69.       username: results.username, 
  70.       password: results.password
  71.       hostname: results.hostname, 
  72.       port: results.port, 
  73.       host: results.host, 
  74.       pathname: results.pathname, 
  75.       search: results.search, 
  76.       path: results.pathname + results.search, 
  77.       hash: results.hash, 
  78.       searchParams: results.searchParams 
  79.     } 
  80.   } 
  81.  
  82.   // url 是為度路徑時(shí),忽略 base 
  83.   if (/^(([^:/?#]+):)/.test(url)) { 
  84.     base = '' 
  85.   } 
  86.  
  87.   // 設(shè)置了基準(zhǔn) URL 
  88.   if (base) { 
  89.     // 移除 base 最后的斜杠 ‘/’ 
  90.     if (/[/]$/.test(base)) { 
  91.       base = base.replace(/[/]$/, ''
  92.     } 
  93.  
  94.     // 確保 url 開(kāi)始有斜杠 
  95.     if (!/^[/]/.test(url)) { 
  96.       url = '/' + url 
  97.     } 
  98.  
  99.     // 保證 URL 地址拼接后是一個(gè)正確的格式 
  100.     url = base + url 
  101.   } 
  102.  
  103.   if (window.ActiveXObject) { 
  104.     return parseURLWithRegExp(url) 
  105.   } else { 
  106.     return parseURLWithURLConstructor(url) 
  107.   } 

 

演示地址:

http://www.yaohaixiao.com/scripts/parseURL/

結(jié)束語(yǔ)

隨著 Web 技術(shù)的不斷發(fā)展,JavaScript 也在不斷地發(fā)展,許多新的 API 接口也不斷的完善,充分的得到各個(gè)主流瀏覽器的支持。我們?cè)陂_(kāi)發(fā)過(guò)程中就必須不斷的關(guān)注新技術(shù)的更新,找到更加靈活便捷的解決方案來(lái)解決開(kāi)發(fā)中的問(wèn)題。

 

本文僅僅是拿解析 URL 信息作為示例,展示使用不同解決方案的一個(gè)實(shí)踐。如果你有什么更好地解析 URL 信息的方式,也歡迎跟我聯(lián)系交流。

 

責(zé)任編輯:華軒 來(lái)源: 今日頭條
相關(guān)推薦

2019-02-26 13:00:11

JavaScriptURL前端

2016-11-14 19:45:39

JavaScript

2010-10-08 12:46:27

Javascriptreplace()

2018-02-23 11:11:11

PythonUrllibURL

2010-10-08 14:27:25

JavascriptSplit

2011-09-09 17:31:45

Android WebJavascript

2011-09-13 09:49:59

PhoneGap插件

2025-04-23 08:20:00

JavaScriptURLAPI

2019-05-28 10:24:31

V8JavaScript延遲

2009-01-19 09:40:53

JavaScript事件代理事件處理器

2021-05-28 09:10:40

JavaScript性能GPU

2024-09-27 09:12:12

JavaScriptscrollTo窗口

2010-03-15 10:49:57

Python函數(shù)變量

2023-05-11 08:00:00

JavaScript柱狀圖

2017-07-07 14:41:13

機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)JavaScript

2009-06-10 21:51:42

JavaScript XMLFirefox

2017-09-12 15:11:12

Chrome

2022-06-07 08:00:00

JavaScript編程語(yǔ)言TSPL

2023-02-01 14:08:53

JavaScriptURL安全

2010-06-11 09:46:55

UML順序圖
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

成人精品视频久久久久| 亚洲石原莉奈一区二区在线观看| 一区高清视频| 国产精品毛片一区二区在线看舒淇| 婷婷综合激情| 亚洲а∨天堂久久精品9966| 黄色一级一级片| 九色porny在线| 国产99久久久精品| 国产精品999| 日本午夜在线观看| youjizz欧美| 欧美午夜电影网| 久久久99精品视频| 国产在线一二三区| 国产91精品精华液一区二区三区 | 在线观看av中文字幕| 日韩av超清在线观看| 一区二区成人在线| 日韩一区不卡| 日韩一级免费视频| 精品夜夜嗨av一区二区三区| 26uuu亚洲国产精品| 日本一级特级毛片视频| 九九精品久久| 337p日本欧洲亚洲大胆色噜噜| 午夜国产一区二区三区| 精精国产xxxx视频在线野外| 亚洲免费在线视频一区 二区| 精选一区二区三区四区五区| 国产成人毛毛毛片| 久久国产婷婷国产香蕉| 国产精品成人aaaaa网站| 国产一卡二卡在线| 亚洲视频电影在线| 精品国产一区二区三区四区在线观看 | 午夜久久久久久久久久| 久久99精品国产麻豆不卡| 青青草原一区二区| 国产一区二区99| 亚洲国产黄色| 欧美精品久久久久久久免费观看| 在线看的片片片免费| 日韩亚洲一区在线| 在线观看国产精品日韩av| 成年人免费观看视频网站| 精品视频在线你懂得| 精品国内二区三区| 国产一线在线观看| 成人精品动漫一区二区三区| 欧美va亚洲va| 50一60岁老妇女毛片| 91蜜桃臀久久一区二区| 精品国产精品网麻豆系列| 国产精品嫩草69影院| 日本免费一区二区三区视频| 欧美一区二区三区思思人| 51自拍视频在线观看| 美女精品视频在线| 亚洲成人黄色在线观看| 亚洲av成人精品一区二区三区| 国产精品qvod| 日韩精品在线观看网站| 成人片黄网站色大片免费毛片| 免费欧美激情| 中文字幕欧美日韩在线| 欧美极品jizzhd欧美18| 91精品高清| 欧美片一区二区三区| 久久久久久久伊人| 欧美专区一区二区三区| 国产精品久久久久久中文字| 国产一区二区三区中文字幕| 国产一区二区剧情av在线| 成人做爰66片免费看网站| 人妻丰满熟妇av无码区hd| 99久久99久久免费精品蜜臀| 奇米影视首页 狠狠色丁香婷婷久久综合 | 国产精品国产亚洲精品| 欧美成人午夜电影| www.自拍偷拍| 99精品全国免费观看视频软件| 九九九久久久久久| 国产精品777777| 日本欧美一区二区三区乱码| 147欧美人体大胆444| 天天躁日日躁狠狠躁喷水| 国产视频一区二区在线| 欧美一级特黄aaaaaa在线看片| 91吃瓜在线观看| 欧美日韩国产在线播放网站| 在线观看视频你懂得| 人人网欧美视频| 视频在线观看99| 日产精品久久久久| 蜜桃av噜噜一区| 国模精品一区二区三区| av大片在线观看| 亚洲国产aⅴ天堂久久| www.日本xxxx| 国产精品流白浆在线观看| 亚洲欧美综合另类中字| 亚洲国产美女视频| 日韩激情av在线| 粉嫩高清一区二区三区精品视频 | 日韩中文理论片| 青娱乐在线视频免费观看| 狂野欧美一区| 国产精品国色综合久久| 国产一二三区在线视频| 亚洲成人动漫一区| 性chinese极品按摩| 欧美黑人做爰爽爽爽| 美女av一区二区三区 | 欧美一区1区三区3区公司| 欧美野外wwwxxx| 欧美日韩综合一区| 免费看污黄网站在线观看| 午夜视频一区| 国产日韩在线亚洲字幕中文| 男人天堂网在线| 婷婷久久综合九色国产成人 | 自拍偷拍精品视频| 91在线观看一区二区| 久久免费一级片| 亚洲欧美专区| 爽爽爽爽爽爽爽成人免费观看| 在线精品免费视| 成人白浆超碰人人人人| 99中文字幕在线观看| 日韩电影精品| 色av中文字幕一区| 精品国产青草久久久久96| 久久青草欧美一区二区三区| 欧美一级欧美一级| 成人福利免费在线观看| 欧美乱大交xxxxx另类电影| 96日本xxxxxⅹxxx17| 欧美极品xxx| 无码日韩人妻精品久久蜜桃| 伊甸园亚洲一区| 欧美最顶级丰满的aⅴ艳星| 内射后入在线观看一区| 亚洲成人av一区二区三区| 国产精品一区二区在线免费观看| 中文字幕人成人乱码| 91免费观看| 欧美性受ⅹ╳╳╳黑人a性爽| 欧美一级生活片| 久草视频手机在线观看| 国产福利电影一区二区三区| 亚洲av综合色区| 中文字幕日韩在线| 色综合久久久888| 亚洲精品久久久久久久久久久久久久| 亚洲精品视频自拍| 四虎精品一区二区| 性色一区二区三区| 日本在线视频不卡| 日韩伦理一区二区| 欧美成年人视频网站欧美| 成人高潮片免费视频| 亚洲成av人片在线观看| av无码一区二区三区| 老司机精品视频网站| 亚洲bbw性色大片| 精品国产一区二区三区2021| 色综合男人天堂| 亚洲欧美综合一区二区| 一本久道中文字幕精品亚洲嫩| 人人爽人人爽人人片| 精品一区二区免费看| 欧美黑人在线观看| 中国av一区| 成人欧美在线视频| brazzers在线观看| 亚洲一区二区久久久| 夜夜躁狠狠躁日日躁av| 亚洲综合免费观看高清完整版 | 亚洲国产精品嫩草影院久久av| 日本国产一区二区三区| 欧美尤物美女在线| 亚洲国产中文字幕久久网 | 色多多在线观看| 中文字幕免费精品一区高清| 亚洲av无码乱码国产麻豆| 精品国产91乱高清在线观看| 国产精品久久久久久久av| 国产乱码字幕精品高清av| 波多野结衣乳巨码无在线| 久久在线播放| 好看的日韩精品视频在线| 99久久久国产精品免费调教网站 | 亚洲精品一区在线观看香蕉| 一级aaaa毛片| 欧美日韩日本国产| 亚洲天堂一级片| 久久精品视频在线免费观看| 色姑娘综合天天| 日韩有码一区二区三区| 国产精品久久久久久久乖乖| 欧美日韩一二| 久久一区免费| 亚洲综合影院| 国产在线精品播放| 日韩欧美一区二区三区免费观看 | 久久综合色播五月| 日本成人在线免费观看| 日本不卡一区二区| 波多野结衣综合网| 一个色综合网| 涩涩涩999| 国产伦精品一区二区三区免费优势| 国产精品丝袜高跟| 成人影院网站| 国产+成+人+亚洲欧洲| 黄在线免费观看| 在线视频亚洲欧美| 亚洲AV成人无码一二三区在线| 91精品国产欧美一区二区成人| 特级西西444www高清大视频| 精品久久久中文| 欧美日韩大片在线观看| 亚洲欧洲日韩av| 久久免费手机视频| 久久久五月婷婷| 久久久久久久久免费看无码| 福利一区二区在线观看| 99日在线视频| 久久精品国产精品亚洲精品| 情侣黄网站免费看| 国产精品色网| 久草青青在线观看| 久久国产免费| 日韩视频第二页| 国产精品尤物| 欧美变态另类刺激| 99成人免费视频| 欧洲精品在线播放| 亚洲午夜视频| 国产3p露脸普通话对白| 精品成人国产| 日本福利视频在线| 裸体一区二区| 在线观看av日韩| 日韩精品每日更新| 日本www.色| 美女一区二区视频| 手机版av在线| 国产一区在线看| 五月天国产视频| 国产成人在线视频播放| www.四虎精品| 99麻豆久久久国产精品免费优播| 一级黄色免费视频| 91麻豆国产在线观看| 熟女丰满老熟女熟妇| 久久免费美女视频| 欧美熟妇激情一区二区三区| 国产精品美女久久久久久2018| 国产福利在线导航| 亚洲精品ww久久久久久p站 | 色综合久久久久网| 999视频在线| 欧美另类久久久品| 亚洲av少妇一区二区在线观看| 亚洲成人激情在线| 国产在线资源| 久久视频在线免费观看| 超碰在线97国产| 国产国语videosex另类| 97精品资源在线观看| 国产富婆一区二区三区| 一区二区小说| 欧美精品一区二区性色a+v| 最新亚洲一区| 亚洲综合色在线观看| 国产精品一色哟哟哟| 加勒比精品视频| 国产精品人妖ts系列视频| 国产女人18水真多毛片18精品| 亚洲成精国产精品女| 人妻中文字幕一区二区三区| 欧美一区二区三区日韩视频| 亚洲欧洲国产综合| 最近免费中文字幕视频2019| 日韩另类在线| 国产精品69精品一区二区三区| 国产精品视频一区二区三区综合 | 欧美在线观看在线观看| zzjj国产精品一区二区| 欧产日产国产精品视频| 成人激情免费在线| 日韩av字幕| 欧美亚洲视频一区| 噜噜噜久久亚洲精品国产品小说| 人妻少妇偷人精品久久久任期| 久久欧美中文字幕| 青娱乐国产在线视频| 欧洲av在线精品| 深爱激情五月婷婷| 久久精品国产亚洲| 日本欧美韩国| 精品无码久久久久国产| 91九色精品国产一区二区| 日本网站免费在线观看| 国产精品99久久久久久宅男| av永久免费观看| 日韩欧美大尺度| 国产刺激高潮av| 久久久精品免费视频| 99久久伊人| 欧美成人免费在线| 亚洲欧洲另类| 9.1在线观看免费| 中文字幕在线播放网址| 欧美日韩人人澡狠狠躁视频| 国产sm主人调教女m视频| 在线观看欧美www| 亚洲欧洲美洲av| 国语精品中文字幕| 欧美片第1页综合| 国产xxxxhd| 亚洲欧美日韩国产另类专区| 伊人网站在线观看| 中文字幕日本精品| 日韩av电影资源网| 日韩精品久久一区二区三区| 六月天综合网| 无码熟妇人妻av| 欧美视频裸体精品| 五月婷婷久久久| 992tv成人免费视频| 大伊香蕉精品在线品播放| www.日本三级| 不卡av在线网| 日韩精品在线不卡| 亚洲成人网av| 理论不卡电影大全神| 国产精品精品软件视频| 亚洲人成人一区二区三区| 国产大尺度视频| 精品久久久久久电影| 四虎影院在线域名免费观看| 5252色成人免费视频| 香蕉精品久久| 国产又大又硬又粗| 国产亚洲欧洲一区高清在线观看| 成人免费视频国产免费| 综合激情国产一区| 午夜精品久久久久久毛片| 欧美 另类 交| 国产成人在线电影| 日本中文字幕免费| 亚洲欧美国产精品| 欧洲成人一区| 三年中国中文在线观看免费播放 | 午夜视频在线观看国产| 香蕉av福利精品导航| 欧洲一区av| 国产精品久久久久7777婷婷| 国产精品久久久久9999赢消| 日本精品一区在线| 亚洲午夜成aⅴ人片| 亚洲欧美色视频| 国产精品午夜视频| 欧美一区久久| 精品无码国产一区二区三区51安| 黑人巨大精品欧美一区二区一视频 | 国产草草影院ccyycom| 欧美夫妻性生活视频| 欧美黄色影院| 日韩av.com| 午夜欧美一区二区三区在线播放| 涩爱av在线播放一区二区| 国产精品欧美久久久| 欧美福利在线| 六月婷婷七月丁香| 欧美一区二区三区的| 性欧美xxx69hd高清| 在线观看日韩片| gogo大胆日本视频一区| 国产在线一级片| 欧美人与性动交a欧美精品| 台湾亚洲精品一区二区tv| 国产一级片自拍| 午夜久久福利影院| 午夜毛片在线| 久久精品丝袜高跟鞋| 九色porny丨国产精品| 日韩美女一级片| 日日狠狠久久偷偷四色综合免费| 9l亚洲国产成人精品一区二三 | 免费成人毛片| 成人免费毛片在线观看| 成人欧美一区二区三区1314| 香蕉视频免费在线看| 91在线色戒在线| 久久久天天操| 五月天婷婷丁香|