上篇简单介绍了一下 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() , 这个接口该怎么使用, 直接去看官方文档就好了, 用起来还是很虚浮的