JavaScript技巧:如何将URL参数解析为对象?

1,548 阅读2分钟

前言

在URL中, 查询参数search值通常用来提供有关的请求信息,因此在前端处理请求逻辑时,了解如何从URL中获取到想要的参数十分重要。在讲解如何解析URL参数为我们想要的对象形式之前,我们先来了解一下网址的组成部分。

URL组成

URL 由多个部分组成。以下面URL为例,通过window.location.href得到完整的URL:

"https://www.baidu.com:80/path/index.html?q=123456&a=b#anchor"

这个 URL 的各个部分组成:

  • 协议:https://,浏览器请求服务器资源的方法,默认HTTP协议
  • 主机:www.baidu.com,资源所在的网站名或服务器的名字,又称域名。在局域网中,有些主机可能没有域名只有IP地址
  • 端口:80,同一个域名下可能包含多个网站,他们之间通过端口区分,默认为80端口
  • 路径:/path/index.html,指向path子目录下的index.html文件
  • 查询参数:q=123456&a=b,提供给服务器的额外信息,每组查询参数都是键值对的形式并通过&连接
  • 锚点:#anchor,网页内部的定位点,浏览器加载页面以后,会自动滚动到锚点所在的位置。

我们通常需要提取的参数就是search提供给服务器的键值对组合,这里是q=123456&a=b

解析URL参数为对象

  1. 直接获取search值并提取,适用于key不重复,且value不包含中文的情况
function urlSearchParse(url){
    //url '?q=123456&a=b'
    let obj = {};
    //提取?后面的值
    let urlArr = url.split('?')[1].split('&');//['q=12345','a=b']
    if(urlArr.length){
        urlArr.forEach((item) => {
            let key = item.split('=')[0];
            let value = item.split('=')[1];
            obj[key] = value;
        })
    }
    console.log(obj);
    return obj;
}
urlSearchParse(window.location.search)
  1. 当key重复时,合并value为数组
function urlSearchParse(url){
    //url '?q=123456&a=b&a=c&a=d'
    let obj = {};
    //提取?后面的值
    let urlArr = url.split('?')[1].split('&');//['q=12345','a=b','a=c','a=d']
    if(urlArr.length){
        urlArr.forEach((item) => {
            let key = item.split('=')[0];
            let value = item.split('=')[1];
            if(key in obj){
                //key重复时,合并value
                let arr = [];
                arr.push(...obj[key])
                arr.push(value)
                obj[key]=value
            }else{
                obj[key] = value;
            }
        })
    }
    console.log(obj);
    return obj;
}
urlSearchParse(window.location.search)
  1. 当value包含中文时,因为URL会自动将中文转为URIstring,所以解析时需要将参数解码

解码方法:

decodeURI: 将URIstring解码(不能解码特殊字符如#、/等)

decodeURIComponent:将URIstring解码(可以解码特殊字符)

function urlSearchParse(url){
     //url '?q=123456&a=b&a=c&a=%E5%AD%97%E7%AC%A6%E4%B8%B2split%E6%96%B9%E6%B3%95'
    let obj = {};
   
    let urlArr = url.split('?')[1].split('&');
    //['q=12345','a=b','a=c','a=%E5%AD%97%E7%AC%A6%E4%B8%B2split%E6%96%B9%E6%B3%95']
    if(urlArr.length){
        urlArr.forEach((item) => {
            //解码为中文
            let key = decodeURI(item.split('=')[0]);
            let value = decodeURI(item.split('=')[1]);
            if(key in obj){
                //key重复时,合并value
                let arr = [];
                arr.push(...obj[key])
                arr.push(value)
                obj[key]=value
            }else{
                obj[key] = value;
            }
        })
    }
    console.log(obj);
    return obj;
}
urlSearchParse(window.location.search)

参考资料:www.bookstack.cn/read/html-t…