上篇简单介绍了一下 Location
对象, 并封装了一个简单处理 URL
的方法, 本篇封装一个处理复杂 URL
的方法
要只是获取一些常规字符串倒没什么难的, 关键还有些乱七八糟的需求, 什么同一个参数名传递了多次啊, 传数组啊. 搞来搞去就写了一大堆
先说说思路吧, 如果你看这文章是想要解决问题, 拿着代码直接用的话, 就直接看最后面的 Code 实现以及使用方法吧
用框架思维分析问题
给你一个如下的 URL
:
将 URL
里传递的参数转换为 object
对象, 这样我们在使用参数的时候也更为方便
我曾多次强调框架思维, 现在遇到这个问题了, 我们就拿框架思维来分析一下, 该怎样才能快速解决
首先是要了解我们的目的是什么? 目的很简单, 取得 URL
内传递的参数, 并且解析成对象
接着再分析我们现在知道些什么? 有一串 URL
我们再来分析, 如果从 URL
中获得传递的参数, 也就是为了达到目的, 我们该做些什么?
URL
的特征我们大致都知道, 就是第一个 ?
后面的字符串, 都是传递的参数, 但是有个特殊情况请不要忘记了, URL
后面有时候会带上一个 #
, 而 #
后面的内容, 并不是我们要传递的参数, 而是网页位置的标识符
如果 URL
中包含了 #
, 我们只需要解析 ?
到 #
之间的字符串就可以了, 如果不包含, 那么第一个 ?
后所有的内容都是我们需要解析的
好了, 分析完后, 我们按照上面的思路来逐步实现, 实现的时候可能会遇到其它的问题, 到时候再分析, 再解决
毕竟再牛逼的工程师, 也不会在动手前就想的面面俱到, 只能是在动手实现前尽可能的考虑周到, 遇到问题时再快速的迭代更新
JS 获取 URL 参数的过程
先用 JS
拿到 URL
, 如果函数传参了 URL
, 那就用参数. 如果没传参, 就使用当前页面的 URL
1 | url = url || window.location.href |
如果后面的字符串存在 #
, 我们还得将 #
后面的字符串去掉, 因为 #
后面的内容并不是我们需要获取的参数, 而是网页位置的标识符
1 | queryString = queryString.split('#')[0] |
好了, 把干扰的部分都移除后, 我们可以开始安心的解析参数了, 先将传递的参数分成数组
1 | var arr = queryString.split('&') |
现在我们可以获得一个字符串数组
1 | ;['a=aa', 'b=bb', 'c', 'd=dd'] |
将字符串拆分成数组后, 我们通过创建一个对象, 用来存储我们所有的参数
1 | var obj = {} |
我们可以通过遍历数组 arr
, 将它拆分成键值对. 把这个字符串做成 key:value
的对象
1 | var a = arr[i].split('=') |
接下来就是要为每一个变量 key
分配对应的值 value
, 如果我们得到的 value
不是一个正确的参数, 我们就用 true
来表示这个参数名存在, 当然了, 你也可以根据自己的实际情况来做改变
1 | var paramName = a[0] |
在这里我只是对 undefined
做了标记, 如果是 NaN
, 我是直接拿它当字符串处理了
在这里有一个小坑得提醒一下, 我们在调用函数, 获取对象取值的时候, 如果 URL
传递的 key
为大写, 我们取对象时写的小写, 那么结果就是为 undefined
比如 URL
为 http://example.com:1234/test/t.asp?TeSt=TEst
, 如果不做大小写的处理, 调用对象取值时 getAllUrlParams().TeSt
才能取到值 TEst
, 如果做了处理, 我们使用时只需要全部写成小写/大写即可, 例如 getAllUrlParams().test
我在这就全部转为小写了, 如果你对大小写要求区分, 那到时候把这段 Code
给去掉就好了
1 | paramName = paramName.toLowerCase() |
接下来我们就要去处理我们接受到的 paramValue
, 这些参数可能是索引数组, 非索引数组, 又或者是常规字符串
如果是索引数组, 我们需要将
paramValue
转换成数组, 并且将索引对应的值, 放入索引对应的位置如果是非索引数组, 我们就要将
paramValue
放到数组中如果只是常规的字符串, 我们就需要为我们的对象
obj
创建一个常规的属性, 并为其分配值.如果这个 key 已经存在, 那么我们就要将现有的
paramValue
从key:value
转换为数组, 并将它放到数组中
拿几个实际案例, 感受一下我们要做什么吧
1 | // 索引数组 |
对应的代码实现如下:
1 | // 如果 paramName 以方括号结束, e.g. colors[] or colors[2] |
如果你的 URL
的传参包含了一些特殊字符, 比如空格. 例如 url="example.com/?name=na%20me"
, 拿到对象值之后, 是需要解码后才能获得正确的值的
1 | var original = getAllUrlParams().name // 'na%20me' |
具体实现以及使用方式
下面是 JS
的具体的完整实现, 你们复制回去就可以用
1 | function getAllUrlParams(url) { |
这个函数该怎么使用呢?
直接把 URL
参数当成对象调用就 OK
咯~
以文章开篇的 URL
为例子
1 | var url = 'http://example.com:1234/test/t.asp?a=aa&b=bb&c&d=dd#Hello' |
你可以在下面输入框中输入需要查询的 url
来体验一下!
不兼容 IE 的解决方案
如果我们不需要考虑 IE 这种妖娆贱货, 以及一些非常老版本浏览器, 就用浏览器内 URLSearchParams 的接口吧… 这个接口可以直接拿取 URL
内的参数
1 | var a = document.createElement('a') |
这个接口还提供了更多成熟的方法, 比如 keys()
, Values()
, 还有 entries()
, 这个接口该怎么使用, 直接去看官方文档就好了, 用起来还是很虚浮的