queryURLParams

693 阅读5分钟

queryURLParams:获取一个URL地址问号传递的参数的值.

问号传参:

  • 在页面跳转的时候,可以基于问号传参传递不同的信息,这样在跳转过去的页面中,就可以基于传递的不同参数信息展示不同的内容(例如:列表页面跳转到详情页面,详情页面展示不同的信息)
  • 在以后我们的vue/react组件开发中,我们也可以基于问号参数实现不同组件之间的信息传递
  • 客户端想要从服务器获取不一样的数据,也可以把一些值基于问号参数的方式传递给服务器端
  • ...

需求:有一个URL地址 "www.yunduo.cn/index.html?…" , 需要我们编写一个方法 queryURLParams,执行这个方法可以获取指定的问号参数信息.

  • 方法:
    • queryURLParams:解析URL地址中的问号参数以及哈希值信息
      • @params
        • url[string]:要解析的URL地址.
        • key[string]:在解析出来的结果中,获取到指定属性的属性值.
      • @return
        • [object|string]全部解析出来的信息或者单一属性的信息. 方法一

        //若当前url中不包括#,这种方法会出问题
        function queryURLParams(url, key) 
        {
            // 获取?和#的索引
            var askIndex = url.indexOf('?'),
                weiIndex = url.indexOf('#');
        
            // 分别获取URL地址中?后面的信息以及#后面的信息
            var askText = url.substring(askIndex + 1, weiIndex);
            var weiText = url.substring(weiIndex + 1);
        
            // 处理最后的结果
            var obj = {};
            obj['_hash'] = weiText; //往obj这个对象里增加一项
            // askText => "lx=0&from=weixin" 先按照&拆成一个数组 ["lx=0", "from=weixin"];
            //    遍历数组中的每一项,每一项继续按照 = 来拆,第一项变为数组["lx","0"] ,第二项变为数组["from","weixin"]
            //    再把每一项拆成的数组中,第一项作为属性名,第二项作为属性值;
            askText.split('&').forEach(function (item)  //item是每次遍历数组中的当前项
                                                        //forEach遍历数组中的每一项时,触发function (item)执行,
                                                        //   每一项都执行function (item)函数中的语句,完成每一项按照 = 来拆,
                                                        //   再把每一项拆成的数组中,第一项作为属性名,第二项作为属性值.                                          
            {
                item = item.split('=');//每一项继续按照 = 来拆,每一项都会变为数组["lx","0"] ["from","weixin"]
                obj[item[0]] = item[1];//将item数组中第一项作为属性名,第二项作为属性值.
            });
            return obj;
        }
        var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
        var res1 = queryURLParams(url);
        console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }

结果为:

image.png

进阶1:容错处理 ,若当前url中不包括#时这种方法不会有问题

        function queryURLParams(url, key) 
        {
            //获取?和#的索引及内容
            var askIndex = url.indexOf('?'),
                weiIndex = url.indexOf('#'),
                askText = '',
                weiText = '',
                obj = {};
            //若#不存在,weiIndex === -1,我们让其等于最末尾的索引(最大索引还要+1)
            //因为当从?往后截的时候,要截取到最后一项并且包含这一项,所以这时weiIndex = url.length-1+1.
            weiIndex === -1 ? weiIndex = url.length : null;
            //若#存在
            if (weiIndex !== url.length) 
            {
                //#存在则获取哈希值
                weiText = url.substring(weiIndex + 1); //从#后面一项截到末尾
                obj['_hash'] = weiText; //往obj这个对象里增加一项
            }
        
            //若?不存在就不处理了 askIndex == -1
            //若?存在则处理?传参信息
            if (askIndex > -1) 
            {
                //存在?则处理?传参信息
                askText = url.substring(askIndex + 1, weiIndex);
                askText.split('&').forEach(function (item) {
                    item = item.split('=');
                    obj[item[0]] = item[1];
                });
            }
            // A||B:A如果是假返回B的值,A如果是真返回A的值(只有五个值是假,其余都是真).
            // A&&B:A如果是假返回A的值,A如果是真返回B的值.
            //若传指定key的值了,则obj对象里返回的只是类型后面的值.
            //如果定义了形参,但执行的时候没有传实参,默认形参的结果是undefined,
                              若传实参了则形参的结果就是传进来的实参.
            //如果没有传实参,则返回obj,若传实参了则返回obj对象里key属性对应的属性值.
            return typeof key !== "undefined" ?(obj[key] || '' ) : obj; 
            //obj[key] || ''  表示如果传进来的key不存在,会返回undefined,若不想让返回undefined,可以让返回空字符串,
            //undefined代表假,当obj[key]为假时即传进来的key不存在,则返回空字符串.
        } 
        var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
        var res1 = queryURLParams(url);
        console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
        var res2 = queryURLParams(url, 'lx');
        console.log(res2); // "0" 

结果为:

image.png

进阶2:简化获取内容的逻辑

       function queryURLParams(url, key) {
            var askText = '',
                weiText = '',
                obj = {};
        
            // 简化获取?和#后面值的操作:利用a元素对象,会把一个URL的各部分解析出来.
            (没有某部分信息,结果是空字符串,如果有这部分信息,则就可以获取这部分内容,对于search是带着?的,hash是带着#的)
            var linkTemp = document.createElement('a'); //<a></a> 动态创建一个a元素标签
            linkTemp.href = url; //把url的地址给a标签的href
            askText = linkTemp.search; //=>?lx=0&from=weixin
            weiText = linkTemp.hash; //=>#video
        
            //此时得到的结果中是带着?和#号的,我们需要把#和?拿掉.
            // #存在则获取哈希值,从索引1开始截.当weiText存在即为1(因为weiText如果不存在返回undefined即为假),
            if(weiText)  //当weiText存在即为1时,
            { 
                obj['_hash'] = weiText.substring(1) : null;
            }
            //weiText ? obj['_hash'] = weiText.substring(1) : null;
        
            // ?存在则处理问号传参信息.
            if (askText) //当askText存在即为1(因为askText如果不存在返回undefined即为假)
            {
                askText = askText.substring(1);//从索引1开始截取 =>"lx=0&from=weixin"这种格式.
                //简化逻辑:基于URLSearchParams简化(这个类就是获取一个问号参数的信息的)
                var usp = new URLSearchParams(askText);
                usp = [...usp.entries()];
                usp.forEach(function (item) {
                    obj[item[0]] = item[1];
                });
            }
            return typeof key !== "undefined" ?
                obj[key] || '' :
                obj;
        } 
        var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
        var res1 = queryURLParams(url);
        console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
        var res2 = queryURLParams(url, 'lx');
        console.log(res2); // "0" 

结果为:

image.png

终极进阶:使用正则几行代码就搞定

         function queryURLParams(url, key) {
            var obj = {};
            //想获得#后面的1到多位的值,只要不是?,=和#.
            url.replace(/#([^?=&#]+)/g, function (_, hash) //一般定义下划线的形参只是为了占位
            //用function (_, hash){}函数生成的的文本替换了/#([^?=&#]+)/g正则表达式匹配的值.
            {
                obj['_hash'] = hash;
            });
            url.replace(/([^?=&#]+)=([^?=&#]+)/g, function (_, key, value) {
                obj[key] = value;
            });
            return typeof key !== "undefined" ?
                obj[key] || '' :
                obj;
        }
        var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
        var res1 = queryURLParams(url);
        console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
        var res2 = queryURLParams(url, 'lx');
        console.log(res2); // "0" 


结果为:

image.png