通常在实际项目中,无论操作数据
、或是dom
,我们需要熟悉一些浏览器
的API
,或是js
原生给我们扩展的API
,我们熟悉了这些API
,某种意义上来说,一些高效的API
和方法
常常会解惑你项目中遇到的很多疑难杂症。
本文只作一些笔者项目中关于URL
常用到的API
,希望在你项目中能带来一点思考和帮助。
正文开始...
location对象
控制台下,window.location
获取浏览器地址URL相关信息
// window.location /* https://www.baidu.com/s?wd=Reflect.%20defineProperty&rsv_spt=1#123 */ const { href, origin, host, port, protocol,pathname, hash, search } = window.location; console.log(href) // 获取整个URL xxx console.log(origin); // 协议+域名+端口 https://www.baidu.com console.log(host); // 主机名+端口号(http或者https会省略端口号) www.baidu.com console.log(port); // '' http默认端口80 https默认端口443 console.log(protocol); // 协议 https: console.log(pathname); // 除了域名的路由地址路径 console.log(hash); // 路径带#的参数 console.log(search); // 地址?后面所有参数
在location.search
、location.hash
、location.origin
、location.href
是通常项目中几个比较高频的获取当前地址的一些参数方法,不过注意只有location.origin
这个是只读的,其他API
都是可读可写
URL
在js
中创建一个地址,使用场景,举个栗子,我们用URL
模拟当前页面的地址
const url = new URL('https://www.baidu.com/s?wd=Reflect.%20defineProperty&rsv_spt=1#123'); console.log(url.search); // ?wd=Reflect.%20defineProperty&rsv_spt=1 console.log(url.hash); // #123 console.log(url.origin); // https://www.baidu.com console.log(url.href);// 'https://www.baidu.com/s?wd=Reflect.%20defineProperty&rsv_spt=1#123'
URL
这个原生构造的地址中属性与location
获取地址上的通用属性都基本一样。唯一的区别是,location
多了replace
与reload
方法,URL
除了拥有location
的通用属性,没有replace
与reload
方法,但是他具备一个获取参数的一个searchParams
API
... console.log(url.searchParams); // { 'wd' => 'Reflect. defineProperty', 'rsv_spt' => '1' } console.log(url.searchParams.toString()); // wd=Reflect.+defineProperty&rsv_spt=1
searchParams
快速获取URL
中携带参数的方法,这个在URL
构建的地址中非常方便。比如现在有一个需求,我需要将一个地址的参数转换成key
与value
的键值对。
以前我们的做法是这样的
function formateQueryUrl () { const { search } = window.location; // 以?分割,获取url上的真正的参数 const [, searchStr] = search.split('?'); // 以&分割前后参数 const arr = searchStr.split('&'); const ret = {}; arr.forEach(v => { const [key, val] = v.split('='); ret[key] = val }); return ret; }
现在我们可以更高效的利用URL
的searchParams
// 与上面formateQueryUrl方法等价 function eazyFormateQueryUrl() { const url = new URL(window.location); return Object.fromEntries(url.searchParams.entries()) } // 如果当前浏览器地址 https://www.badu.com?a=1&b=2 // {a:1,b:2}
这个eazyFormateQueryUrl
方法是不是很简单,两行代码就搞定了格式化url
中的参数,并且将一串字符串参数轻松的转换成了对象
注意上面的方法我们使用了Object.fromEntries
与url.searchParams.entries()
,其实url.searchParams
的构造函数就是URLSearchParams
,而URLSearchParams
是一个具有可迭代器
功能的API,所以你可以for...of
或者entries
操作。
同时我们注意fromEntries
,我们看下这个API
,通常我们不常用,一般我们都是entries
操作得多,但是实际上fromEntries
就是还原对象的entries
操作,这里我们就是利用了这一点。
举个栗子
const ret = {name: 'Maic', public: 'Web技术学苑'}; const arr = Object.entries(ret); console.log(arr) // [['name', 'Maic'], ['public', 'Web技术学苑']]
如果你想将arr
还原成以前的对象,那么你肯定想到循环的做法,像下面这样
... const target = {}; arr.forEach(item => { const [key, val] = item; target[key] = val; }); console.log(target); // {name: 'Maic', public: 'Web技术学苑'}
其实不用循环,原生Object提供了一个API
,它可以将entries
数据还原成以前的。那么我们可以简单实现
const ret = {name: 'Maic', public: 'Web技术学苑'}; const arr = Object.entries(ret); /* const target = {}; arr.forEach(item => { const [key, val] = item; target[key] = val; }); */ // 与下面等价 const target = Object.fromEntries(arr) // {name: 'Maic', public: 'Web技术学苑'}
正因为如此,我们利用了fromEntries
的这点特性,巧妙的将原数据进行转对象了。
对于URL
,我们还需要可以动态的添加路径,比如下面一个栗子
function locationByNamePath (path) { const { origin } = window.location; const url = new URL(path, origin); window.location.href = url.href; } locationByNamePath('/index.html'); // https://www.baidu.com/index.html locationByNamePath('/about.html'); // https://www.baidu.com/about.html
URLSearchParams
这个API
是一个原生的构造函数,可以获取地址?
后面的参数信息
举个栗子
var urlSearch = new URLSearchParams(window.location.search); console.log(`${urlSearch}`); // 打开百度,在控制台随便输入关键字搜索,控制台复制该断代码,就可以看到
URLSearchParams
传入字符串
const search = new URLSearchParams('a=1&b=2&c=3'); console.log(search.toString()) // a=1&b=2&c=3
等价于
const search = new URLSearchParams(window.location.search); console.log(search.toString()) // a=1&b=2&c=3
URLSearchParams
传入数组,将一个对象转换成url
参数,通常在ajax
get请求拼接参数时,可能很有用
const obj = {a:1,b:2,c:3}; const search2 = new URLSearchParams(Object.entries(obj)); console.log(search2.toString()); //a=1&b=2&c=3 $.ajax({ url: `xxxx?${search2}`, methods: 'get' })
当我们使用fetch
原生api
请求时,new URLSearchParams
可以作为body
参数
const params = { name: 'maic', password: '123456' } fetch('https://baidu.com', { methods: 'POST', body: new URLSearchParams(params) })
我们知道URLSearchParams
具有可迭代器属性的特征,因此它像Map
、Set
一样具有增删查改
的特性
查
get获取参数值
const obj = {a:1,b:2,c:3}; const search2 = new URLSearchParams(Object.entries(obj)); console.log(search2.get('a')); // 1 console.log(search2.get('b')); // 2 console.log(search2.get('c')); // 3
增
append,添加某个参数
... search2.append('d', 'hello') // a=1&b=2&c=3&d=hello
删
delete删除某个参数
... search2.delete('a'); console.log(search2.toString()); //b=2&c=3
改
set修改参数
const obj = {a:1,b:2,c:3}; const search2 = new URLSearchParams(Object.entries(obj)); search2.set('a', '666') console.log(`${search2}`); // a=666&b=2&c=3&d=hello
是否存在
has判断有没有key
... console.log(search2.has('a')); // true
获取URLSearchParams
所有的key
或者value
new URLSearchParams({a:1,b:2,c:3}).keys()
,new URLSearchParams({a:1,b:2,c:3}).values()
const obj = {a:1,b:2,c:3}; const search2 = new URLSearchParams(Object.entries(obj)); const keys = Array.from(search2.keys()); console.log(keys); // ['a', 'b', 'c'] const values = Array.from(search2.values()); // ['1', '2', '3']
对于URLSearchParams
可以传字符串
,可以是对象
或是数组
,当我们获取URLSearchParams
的key,直接调用xxx.keys()
或者是xxx.values()
,不过这样取出的值是一个迭代器,还需要用Array.from
中转一下。
还原URLSearchParams
参数
... Object.fromEntries(search2.entries()); // {a:1,b:2,c:3}
总结
location
常用获取hostname
、origin
、search
、hash
等
URL
创建url,并且拥有searchParams
获取url中的?
后面的参数
- 利用
URLSearchParams
高效格式化url
参数,两行代码实现了格式化?
参数
URLSearchParams
这个API
可以直接获取url参数,并提供增删查改
[append、delete、get、set、has]方法