兩個 API 接口定義
URL() 構造函數返回一個新創建的 URL 對象,表示由一組參數定義的 URL。
URLSearchParams 接口定義了一些實用的方法來處理 URL 的查詢字符串。
快速了解兩個 API 在哪里用
以前我們要對地址欄中的 URL 地址進行分析處理,需要自己進行字符串分析,例如:
https://mybj123.com/?s=css
我們想要知道 s 參數后面的值是什么,往往需要進行字符切割匹配,要么正則匹配。
實際上,現在,瀏覽器已經有了內置的 API 接口可以對 URL 進行處理,這個 API 就是 URLSearchParams()以及 URL()。
例如獲取 s 的查詢參數值,可以直接下面這樣:
new URL('https://mybj123.com/?s=css').searchParams.get('s');
或者
new URLSearchParams('?s=css').get('s');
URLSearchParams()語法
語法
// URL 查詢字符串
var myUrlSearchParams = new URLSearchParams(strSearchParams);
// 查詢字符序列
var myUrlSearchParams = new URLSearchParams(arrSearchSequence);
// 查詢鍵值對象
var myUrlSearchParams = new URLSearchParams(objSearchKeyValue);
參數
strSearchParams
URL 查詢字符串。使用示意:
var params1 = new URLSearchParams('?s=url');
或者對當前地址欄地址的查詢字符串進行實例化:
var params2 = new URLSearchParams(location.search);
arrSearchSequence
數組形式的查詢字符序列。例如:
var params3 = new URLSearchParams([['s', 'url'], ['someId', 1]]);
objSearchKeyValue
鍵值對形式的查詢對象。例如:
var params4 = new URLSearchParams({"s": "url", "someId": 2})
URLSearchParams 實例方法
上面執行 new URLSearchParams()的返回值 myUrlSearchParams 就是一個 URLSearchParams 實例。
這個 URLSearchParams 實例包含眾多方法,具體如下:
URLSearchParams.append(name,key)
添加新的鍵值對作為查詢參數。例如:
var params = new URLSearchParams('?s=url'); // 也可以沒有問號直接's=url'
params.append('from', 'mybj');
// 此時的查詢字符串是:'s=url&from=mybj'
URLSearchParams.delete(name)
刪除已存在的查詢參數。例如:
var params = new URLSearchParams('?s=url');
params.delete('s');
// 此時的查詢字符串是:''
URLSearchParams.entries()
返回查詢參數們的迭代器對象,我們可以迭代該迭代器對象獲得所有的鍵值對。例如使用 for..of:
var searchParams = new URLSearchParams("s=url&from=mybj");
// 顯示所有的鍵值對
for (var pair of searchParams.entries()) {console.log(pair[0]+ ', '+ pair[1]);
}
URLSearchParams.forEach(callback)
此方法可以遍歷查詢對象。
其中 callback 是遍歷方法,支持兩個參數,分別是每個鍵值對的值和鍵。示意:
var searchParams = new URLSearchParams("s=url&from=mybj");
// 輸出值和鍵的內容
searchParams.forEach(function(value, key) {console.log(value, key);
});
URLSearchParams.get(name)
返回指定關鍵字對象的值。例如:
var params = new URLSearchParams('s=url&from=mybj');
params.get('s');
// 返回值是:'url'
如果沒有對應的值,則返回 null。
URLSearchParams.getAll(name)
以數組形式返回所有當前查詢關鍵字對應的值,例如:
var params = new URLSearchParams('s=url&s=urlsearchparams&from=mybj');
params.getAll('s');
// 返回值是:['url', 'urlsearchparams']
URLSearchParams.has(name)
返回布爾值,true 或者 false,是否包含某個查詢關鍵字。
var params = new URLSearchParams('?s=url');
params.has('s') == true; // true
URLSearchParams.keys()
返回一個迭代器對象,允許迭代該對象中所有的關鍵字。使用示意:
var searchParams = new URLSearchParams("s=url&from=mybj");
// 顯示所有的鍵
for (var key of searchParams.keys()) {console.log(key);
}
URLSearchParams.values()
返回一個迭代器對象,允許迭代該對象中所有的關鍵字值。使用示意:
var searchParams = new URLSearchParams("s=url&from=zxx");
// 顯示所有的值
for (var value of searchParams.values()) {console.log(value);
}
URLSearchParams.set(name,value)
有則替換,無則加冕。例如:
var params = new URLSearchParams('s=url&s=urlsearchparams&from=mybj');
params.set('s', 'css 世界');
params.getAll('s'); // 返回值是:['css 世界']
可以看到會替換之前所有的’s’查詢參數值。下面這個例子展示“無則加冕”:
var params = new URLSearchParams('s=url');
params.set('from', 'mybj');
params.toString(); // 結果是:'s=url&from=mybj'
也就是原本沒有對應參數的時候會添加這個參數。
URLSearchParams.sort()
方法將此對象中包含的所有鍵/值對就地排序,并返回 undefined。排序順序根據鍵的 Unicode 碼位。該方法使用一種穩定的排序算法(即保留具有相同鍵的鍵/值對之間的相對順序)。例如:
var searchParams = new URLSearchParams('c=4&a=2&b=3&a=1');
// 鍵值對排序
searchParams.sort();
// 顯示排序后的查詢字符串
console.log(searchParams.toString()); // 結果是:a=2&a=1&b=3&c=4
URLSearchParams.toString()
把 URLSearchParams 對象轉換成查詢字符串。這個代碼示意上面多次出現,這里不重復展示。
URLSearchParams()兼容性
Edge17+支持。
URL()語法
URL 接口用于解析、構造、規范化和編碼 URL。其構造的實例支持若干屬性和方法,可以用來讀寫 URL 相關的屬性值。我們甚至可以把文件內容作為 URL 的一部分進行呈現。
在使用 URL()之前,建議先做個瀏覽器支持與否的判斷,例如:
if (window.URL) {// ...
}
另外,URL 接口支持在 web workers 中使用。
語法
var myUrl = new URL(url, [base])
參數
url
相對地址或者絕對地址。如果是相對地址,需要設置 base 參數,如果是絕對地址,則會忽略 base 設置。我們也可以使用 URL 對象作為 url 參數。此時作用的值是 URL 對象中的 href 屬性值。
base
如果 URL 地址是相對地址,則需要這個參數,作用是作為相對計算的基礎地址。我們也可以使用 URL 對象作為 base 參數,此時作用的值是 URL 對象中的 href 屬性值。如果不設置該參數,則會按照空字符串”進行處理。
如果參數值無法組合成完整 URL 地址,則會報 TypeError 錯誤。
測試與用法示意
基本使用示意:
var base = 'https://mybj123.com';
// 結果是:https://mybj123.com/aboutus
console.log(new URL('aboutus', base).href);
// 結果是:https://mybj123.com/aboutus
console.log(new URL('/aboutus', base).href);
可以直接使用 URL 對象作為參數:
var base = 'https://mybj123.com';
var urlFromBase = new URL('aboutus', base);
// 結果是:https://mybj123.com/aboutus
console.log(new URL(urlFromBase).href);
// 結果是:https://mybj123.com/sitemaps
console.log(new URL('sitemaps', urlFromBase).href);
下面是帶有較深層級 base 地址和不同相對地址形式的測試:
var base = 'https://mybj123.com/study/a/b/c';
// 結果是:https://mybj123.com/study/a/sp/icon
console.log(new URL('sp/icon', base).href);
// 結果是:https://mybj123.com/study/a/sp/icon
// 上下結果對比表明./和裸露相對地址沒有區別
console.log(new URL('./sp/icon', base).href);
// 結果是:https://mybj123.com/study/sp/icon
// 向上一層 URL 層級深度
console.log(new URL('../sp/icon', base).href);
// 結果是:https://mybj123.com/study/a/sp/icon
// 層級按照斜杠來算的
console.log(new URL('../sp/icon', base + '/').href);
// 結果是:https://mybj123.com/sp/icon
// 斜杠開頭表示跟地址開始匹配
console.log(new URL('/sp/icon', base).href);
下面是不同域名之間的測試:
var base = 'https://mybj123.com';
// 結果是:http://image.mybj123.com 和 https://image.mybj123.com
// 沒有協議的 url 認為是相對地址,協議取自 base 地址
console.log(new URL('//image.mybj123.com', 'https://mybj123.com').href);
console.log(new URL('//image.mybj123.com', 'https://mybj123.com').href);
// 結果是:https://image.mybj123.com
// 這里 url 是完整的絕對地址,因此,忽略后面的 base 參數
console.log(new URL('https://image.mybj123.com', base).href);
下面是出錯的測試:
// 沒有絕對地址,會報錯
console.log(new URL('').href);
console.log(new URL('//image.mybj123.com').href);
URL 實例對象的屬性和方法
new URL()返回值就是一個實例對象,包括下面這些屬性和方法。
屬性
已知有 URL 地址如下:
var url = new URL('https://www.xxx.com:80/wordpress/?s=url#comments');
var ftp = new URL('ftp://username:password@192.168.1.1/path/file');
hash
URL 地址中的錨鏈值,包含字符串’#’,例如這里 url.hash 的返回值是’#comments’。
host
URL 地址中 host 主機地址,包括協議端口號,這里 url.host 的返回值是’www.xxx.com:80’。
hostname
URL 地址中主機名稱,不包括端口號,這里 url.hostname 的返回值是’www.xxx.com’。
href
完成的 URL 地址。
origin[只讀]
返回 URL 地址的來源,會包含 URL 協議,域名和端口。這里 url.origin 的返回值是’https://www.xxx.com:80’。
password
返回 URL 地址域名前的密碼。ftp 協議中比較常見。這里 ftp.password 的返回值是’password’。
username
返回 URL 地址域名前的用戶名。ftp 協議中比較常見。這里 ftp.username 的返回值是’username’。
pathname
返回 URL 中的目錄+文件名。例如這里 ftp.pathname 的返回值是’/path/file’。
port
返回 URL 地址中的端口號。例如這里 url.port 的返回值是’80’,ftp.port 的返回值是”。
protocol
返回 URL 地址的協議,包括后面的冒號’:’。例如這里 url.protocol 的返回值是’https:’,ftp.protocol 的返回值是’ftp:’。
search
返回 URL 地址的查詢字符串,如果有參數,則返回值以問號’?’開頭。例如這里 url.search 的返回值是’?s=url’。
searchParams
返回一個 URLSearchParams 對象,可以調用 URLSearchParams 對象各種方法,對查詢字符串進行非常方便的處理。例如我們想要知道查詢關鍵字 s 對應的值,可以:
url.searchParams.get('s');
方法
toString()
返回的完整的 URL 地址,你可以理解為 URL.href 的另外一種形式,不過這個只能輸出,不能修改值。
toJSON()
同樣返回完整的 URL 地址,返回的字符串和 href 屬性一樣。
靜態方法
URL.createObjectURL(object)
可以把 File,Blob 或者 MediaSource 對象變成一個一個唯一的 blob URL。其中參數 object 可以是 File,Blob 或者 MediaSource 對象。
URL.revokeObjectURL(objectURL)
撤消之前使用 URL.createObjectURL()創建的 URL 對象。其中參數 objectURL 表示之前使用 URL.createObjectURL()創建的 URL 返回值。
靜態方法實際使用案例一則
我們使用 Ajax 請求一個跨域圖片避免 canvas 跨域生成問題的時候可以使用這兩個靜態方法:
var xhr = new XMLHttpRequest();
xhr.onload = function () {var url = URL.createObjectURL(this.response);var img = new Image();img.onload = function () {// 此時你就可以使用 canvas 對 img 為所欲為了// ... code ...// 圖片用完后記得釋放內存URL.revokeObjectURL(url);};img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();
兼容性
Edge 12+支持。
這兩個 JS API 的 polyfill
從兼容性表可以看出,URLSearchParams Edge 17 才開始支持,而 URL 從 Edge 12 才開始支持,似乎兼容性不佳,但是,這并不妨礙我們在實際項目中使用,為什么呢?因為有 polyfill。
這里有一個一直支持到 ES7 最新規范的 URL 和 URLSearchParams?polyfill 項目
按照官方說法,兼容到 IE 10+。
IE9 究竟支不支持,還是僅僅是部分支持,我大致簡單測試了一下,結論如下:
除了 URL()幾個靜態方法以外的基本使用 IE9 都是支持的!
對于我來說,夠用了夠用了。
如果以后實際應用發現其他細節再更新。
結束語
web 這塊,無論是 CSS,HTML 還是 JS API 都在不斷進步,標準且跨平臺,以前很多需要自定義的方法和特性,現在瀏覽器都已經原生支持,以前的那些語言框架價值越來越低。
是時候開始嘗試擁抱原生,辛苦地學習與積累,簡單且輕松的實現,面向產品,面向用戶,立足未來,方能穿越長河。
更多精彩內容https://mybj123.com/4510.html