urlSearch的信息处理以及URLSearchParams

location.search和HTMLHyperlinkElementUtils.search都包含URL参数的一个DOMString,开头有一个“?”。

location对象不用多说,其search属性是一个可读可写的字符串,可设置或返回当前 URL 的查询部分。

如,某页面url为http://blog.michealwayne.cn/index.html?id=wayne&year=2019&month=06&date=19,其location.search为

1
console.log(location.search);		// "?id=wayne&year=2019&month=06&date=19"

如果要修改,可以直接赋值操作,如

1
location.search = '?id=micheal&fulldate=2019-06-19';

其中第一位’?’可省略,同

1
location.search = 'id=micheal&fulldate=2019-06-19';

此时页面将重新加载,浏览器地址栏的url也将替换

与location.search类似,HTMLHyperlinkElementUtils.search属性是一个可读可写的字符串,但它作用于DOM锚点元素,可设置或返回当前 URL 的查询部分。


1
2
3
<body>
<a id="test" href="http://blog.michealwayne.cn/index.html?id=wayne&year=2019&month=06&date=19">test link</a>
</body>

其HTMLHyperlinkElementUtils.search为

1
console.log(document.getElementById('test').search);	// "?id=wayne&year=2019&month=06&date=19"

如果要修改,可以直接赋值操作,如

1
document.getElementById('test').search = '?id=micheal&fulldate=2019-06-19';

其中第一位’?’可省略,同

1
document.getElementById('test').search = 'id=micheal&fulldate=2019-06-19';

2.通过location.search获取信息

很多时候,页面间跳转需要传递数据信息,或者客户端打开webview时需要传值。这种时候因为跨域等原因无法或不适合用Storage以及cookie来记录传递,这时候最普遍的做法就是通过search参数或hash参数(hash参数在本文不做介绍)。

还是刚才的地址(http://blog.michealwayne.cn/index.html?id=wayne&year=2019&month=06&date=19),那么该如何获取带来的字段信息呢?

location.search字符串解析

search参数携带的信息键值对一般以key=value的形式展示,多个键值对之间以’&’字符进行拼接,由此规则我们可以用以下函数进行对location.search的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @function getUrlParam
* @description 根据参数获取location.search信息
* @param {String} name 键值
* @param {Boolean} decode 指定decode方式
* @return {String} 参数值
*/
function getUrlParam (name, decode) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
let r = window.location.search.substr(1).match(reg); //匹配目标参数

if (r) {
if (!decode) {
return decodeURI(r[2]);
} else {
return eval(decode + '(r[2])');
}
}
return null;
}

其中为何要用decodeURI()方法进行解码呢?主要是因为中文等字符在url中会被编码,比如http://blog.michealwayne.cn/index.html?name=吴彦祖,其search为

1
console.log(location.search);	// "?name=%E5%90%B4%E5%BD%A6%E7%A5%96"

这时要转回中文的话就需要借助decodeURI()方法。

通过上面的函数,我们可以拿到所需要的字段信息

1
2
3
4
5
getUrlParam('id');	// "wayne"
getUrlParam('year'); // "2019"
getUrlParam('month'); // "06"
getUrlParam('date'); // "19"
getUrlParam('hahaha'); // null

那么除了通过自定义的search解析方法外还有更快捷的途径吗?这就是接下来要介绍的URLSearchParams()对象。

3.URLSearchParams()

URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。其构造函数为:URLSearchParams()。

URLSearchParams提供以下方法:

  • append(): 插入一个指定的键/值对作为新的搜索参数。
  • delete(): 从搜索参数列表里删除指定的搜索参数及其对应的值。
  • entries():返回一个iterator可以遍历所有键/值对的对象。
  • get():获取指定搜索参数的第一个值。
  • getAll():获取指定搜索参数的所有值,返回是一个数组。
  • has():返回 Boolean 判断是否存在此搜索参数。
  • keys():返回iterator 此对象包含了键/值对的所有键名。
  • set():设置一个搜索参数的新值,假如原来有多个值将删除其他所有的值。
  • sort():按键名排序。
  • toString():返回搜索参数组成的字符串,可直接使用在URL上。
  • values():返回iterator 此对象包含了键/值对的所有值。

还是刚才的地址(http://blog.michealwayne.cn/index.html?id=wayne&year=2019&month=06&date=19),那么该如何获取带来的字段信息呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let searchParams = new URLSearchParams(location.search);

searchParams.get('id'); // 'wayne'
searchParams.get('year'); // '2019'

searchParams.has('month'); // true
searchParams.has('hahaha'); // false

searchParams.append('name', '吴彦祖');
searchParams.toString(); // "id=wayne&year=2019&month=06&date=19&name=%E5%90%B4%E5%BD%A6%E7%A5%96"

searchParams.sort();
searchParams.delete('year');
searchParams.toString(); // "date=19&id=wayne&month=06&name=%E5%90%B4%E5%BD%A6%E7%A5%96"

URLSearchParams()对象无疑对search的操作提供了更灵活、全面的操作,只是它的兼容并不够好:

URLSearchParams compatibility

Android需要5及以上,ios需要10.3及以上,IE全军覆没。

当然我们可以通过封装做到向下兼容,也就是

url-search-params-polyfill

npm url-search-params-polyfill
安装:

1
npm i -D url-search-params-polyfill

使用同 URLSearchParams()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import 'url-search-params-polyfill'

// new an empty object
var search1 = new URLSearchParams();

// from a string
var search2 = new URLSearchParams("id=1&from=home");

// from an object
var search3 = new URLSearchParams({ id: 1, from: "home" });

// from location.search, will remove first "?" automatically
var search4 = new URLSearchParams(window.location.search);

// from anther URLSearchParams object
var search5 = new URLSearchParams(search2);


参考资料