url = url || window.location.href
var queryString = url.split('?')[1]
如果后面的字符串存在 #
, 我们还得将 #
后面的字符串去掉, 因为 #
后面的内容并不是我们需要获取的参数, 而是网页位置的标识符
queryString = queryString.split('#')[0]
好了, 把干扰的部分都移除后, 我们可以开始安心的解析参数了, 先将传递的参数分成数组
var arr = queryString.split('&')
现在我们可以获得一个字符串数组
['a=aa', 'b=bb', 'c', 'd=dd']
将字符串拆分成数组后, 我们通过创建一个对象, 用来存储我们所有的参数
var obj = {}
我们可以通过遍历数组 arr
, 将它拆分成键值对. 把这个字符串做成 key:value
的对象
var a = arr[i].split('=')
接下来就是要为每一个变量 key
分配对应的值 value
, 如果我们得到的 value
不是一个正确的参数, 我们就用 true
来表示这个参数名存在, 当然了, 你也可以根据自己的实际情况来做改变
var paramName = a[0]
var paramValue = typeof a[1] === 'undefined' ? true : a[1]
在这里我只是对 undefined
做了标记, 如果是 NaN
, 我是直接拿它当字符串处理了
在这里有一个小坑得提醒一下, 我们在调用函数, 获取对象取值的时候, 如果 URL 传递的 key
为大写, 我们取对象时写的小写, 那么结果就是为 undefined
比如 URL 为 http://example.com:1234/test/t.asp?TeSt=TEst
, 如果不做大小写的处理, 调用对象取值时 getAllUrlParams().TeSt
才能取到值 TEst
, 如果做了处理, 我们使用时只需要全部写成小写/大写即可, 例如 getAllUrlParams().test
我在这就全部转为小写了, 如果你对大小写要求区分, 那到时候把这段 Code 给去掉就好了
paramName = paramName.toLowerCase()
接下来我们就要去处理我们接受到的 paramValue
, 这些参数可能是索引数组, 非索引数组, 又或者是常规字符串
如果是索引数组, 我们需要将 paramValue
转换成数组, 并且将索引对应的值, 放入索引对应的位置
如果是非索引数组, 我们就要将 paramValue
放到数组中
如果只是常规的字符串, 我们就需要为我们的对象 obj
创建一个常规的属性, 并为其分配值.
如果这个 key 已经存在, 那么我们就要将现有的 paramValue
从 key:value
转换为数组, 并将它放到数组中
拿几个实际案例, 感受一下我们要做什么吧
// 索引数组
getAllUrlParams('http://example.com/?colors[0]=red&colors[2]=green&colors[6]=blue')
// { "colors": [ "red", null, "green", null, null, null, "blue" ] }
// 非索引数组
getAllUrlParams('http://example.com/?colors[]=red&colors[]=green&colors[]=blue')
// { "colors": [ "red", "green", "blue" ] }
// 多次传递同一个key
getAllUrlParams('http://example.com/?colors=red&colors=green&colors=blue')
// { "colors": [ "red", "green", "blue" ] }
// 传递了key,但是没传value
getAllUrlParams('http://example.com/?product=shirt&color=blue&newuser&size=m')
// { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }
对应的代码实现如下:
// 如果 paramName 以方括号结束, e.g. colors[] or colors[2]
if (paramName.match(/\[(\d+)?\]$/)) {
// 如果 paramName 不存在,则创建 key
var key = paramName.replace(/\[(\d+)?\]/, '')
if (!obj[key]) obj[key] = []
// 如果是索引数组 e.g. colors[2]
if (paramName.match(/\[\d+\]$/)) {
// 获取索引值并在对应的位置添加值
var index = /\[(\d+)\]/.exec(paramName)[1]
obj[key][index] = paramValue
} else {
// 如果是其它的类型,也放到数组中
obj[key].push(paramValue)
} else {
// 处理字符串类型
if (!obj[paramName]) {
// 如果如果 paramName 不存在,则创建对象的属性
obj[paramName] = paramValue
} else if (obj[paramName] && typeof obj[paramName] === 'string') {
// 如果属性存在,并且是个字符串,那么就转换为数组
obj[paramName] = [obj[paramName]]
obj[paramName].push(paramValue)
} else {
// 如果是其它的类型,还是往数组里丢
obj[paramName].push(paramValue)
如果你的 URL 的传参包含了一些特殊字符, 比如空格. 例如 url="example.com/?name=na%20me"
, 拿到对象值之后, 是需要解码后才能获得正确的值的
var original = getAllUrlParams().name // 'na%20me'
var decode = decodeURIComponent(original) // 'na me'
具体实现以及使用方式
下面是 JS 的具体的完整实现, 你们复制回去就可以用
function getAllUrlParams (url) {
// 用 JS 拿到 URL,如果函数接收了 URL,那就用函数的参数。如果没传参,就使用当前页面的 URL
url = url || window.location.href
var queryString = url.split('?')[1]
// 用来存储我们所有的参数
var obj = {}
// 如果没有传参,返回一个空对象
if (!queryString) {
return obj
// # 后的内容不是我们需要的
queryString = queryString.split('#')[0]
// 将参数分成数组
var arr = queryString.split('&')
for (var i = 0; i < arr.length; i++) {
// 分离成 key:value 的形式
var a = arr[i].split('=')
// 将 undefined 标记为 true
var paramName = a[0]
var paramValue = typeof a[1] === 'undefined' ? true : a[1]
// 如果调用对象时要求大小写区分,可删除这行代码
paramName = paramName.toLowerCase()
// 如果 paramName 以方括号结束, e.g. colors[] or colors[2]
if (paramName.match(/\[(\d+)?\]$/)) {
// 如果 paramName 不存在,则创建 key
var key = paramName.replace(/\[(\d+)?\]/, '')
if (!obj[key]) obj[key] = []
// 如果是索引数组 e.g. colors[2]
if (paramName.match(/\[\d+\]$/)) {
// 获取索引值并在对应的位置添加值
var index = /\[(\d+)\]/.exec(paramName)[1]
obj[key][index] = paramValue
} else {
// 如果是其它的类型,也放到数组中
obj[key].push(paramValue)
} else {
// 处理字符串类型
if (!obj[paramName]) {
// 如果如果 paramName 不存在,则创建对象的属性
obj[paramName] = paramValue
} else if (obj[paramName] && typeof obj[paramName] === 'string') {
// 如果属性存在,并且是个字符串,那么就转换为数组
obj[paramName] = [obj[paramName]]
obj[paramName].push(paramValue)
} else {
// 如果是其它的类型,还是往数组里丢
obj[paramName].push(paramValue)
return obj
这个函数该怎么使用呢?
直接把 URL 参数当成对象调用就 OK 咯~
以文章开篇的 URL 为例子
var url = 'http://example.com:1234/test/t.asp?a=aa&b=bb&c&d=dd#Hello'
var urlParams = getAllUrlParams(url)
urlParams.a // 'aa'
urlParams.b // 'bb'
urlParams.c // true
urlParams.NB // undefined
你可以在下面输入框中输入需要查询的 url 来体验一下!
不兼容 IE 的解决方案
如果我们不需要考虑 IE 这种妖娆贱货, 以及一些非常老版本浏览器, 就用浏览器内 URLSearchParams 的接口吧. . . 这个接口可以直接拿取 URL 内的参数
var a = document.createElement('a')
a.href = 'http://example.com:1234/test/t.asp?a=aa&b=bb&c&d=dd#Hello'
var urlParams = new URLSearchParams(a.search) // 使用 search 时注意 # 和 ? 的先后位置
// 判断参数是否存在
console.log(urlParams.has('a')) // true
// 获取参数对应的值
console.log(urlParams.get('a')) // 'aa'
这个接口还提供了更多成熟的方法, 比如 keys()
, Values()
, 还有 entries()
, 这个接口该怎么使用, 直接去看官方文档就好了, 用起来还是很虚浮的