手写queryURLParams

480 阅读2分钟

本文有参考qs库的源码

要求:

let str = 'http://www.xxx.com/?lx=0&from=weixin&n=100#video';
console.log(str.queryURLParams()); //=>{lx:0,from:'weixin',n:100,HASH:'video'}
console.log(str.queryURLParams('lx')); //=>0
console.log(str.queryURLParams('HASH')); //=>video

问号传参的作用:

  • 客户端页面跳转的时候,基于问号传递参数实现数据的传输
  • 客户端向服务器端发送请求,GET系列请求都是基于问号参数实现的数据传递的
  • 前端路由中,组件和组件之间的通信也可以基于问号传参
  • ...

问号传递参数的格式: urlencoded

数据被编码成以 '&' 分隔的键-值对, 同时以 '=' 分隔键和值。

具体查看MDN content type application/x-www-form-urlencoded

queryURLParams 是项目中一个非常常用的获取问号参数的方法。

三种方法手写实现:

字符串截取处理

String.prototype.queryURLParams = function queryURLParams(attr) {
    let self = this,
        obj = {};
     let askIndex = self.indexOf('?'),
        wellIndex = self.indexOf('#'),
        askText = '',
        wellText = '';
    askIndex === -1 ? askIndex = self.length : null;
    wellIndex === -1 ? wellIndex = self.length : null;
    if (askIndex < wellIndex) {//判断?和#哪个在前面
    //'http://www.xxx.com/#video?lx=0&from=weixin&n=100'
        askText = self.substring(askIndex + 1, wellIndex);
        wellText = self.substring(wellIndex + 1);
    } else {
        askText = self.substring(askIndex + 1);
        wellText = self.substring(wellIndex + 1, askIndex);
    }
    // 井号获取信息了
    if (wellText) obj['HASH'] = wellText;
    // 问号获取信息了
    if (askText) {
        askText.split('&').forEach(item => {
            let [key, value] = item.split('=');//解构赋值
            obj[key] = value;
        });
    } 

    return typeof attr === "undefined" ? obj : (obj[attr] || '');
}; 

利用A元素对象的相关属性(OOP)

a DOM对象中的属性: hash/host/hostname/pathname/protocol/search ... 基于这些私有属性即可获取到URL中每一部分的信息

image。png

image。png

String.prototype.queryURLParams = function queryURLParams(attr) {
   let self = this,
       obj = {};
   let link = document.createElement('a');
   link.href = self;
   let {
       search,
       hash
   } = link;
   link = null;//手动释放内存
   if (hash) obj['HASH'] = hash.substring(1);
   if (search) {
       search.substring(1).split('&').forEach(item => {
           let [key, value] = item.split('=');
           obj[key] = value;
       });
   }

   return typeof attr === "undefined" ? obj : (obj[attr] || '');
}; 

直接正则处理

正则 /[^?&=#]/ 意义:等号两边不能是这几个符号,因为这几个符号是有特殊含义的

String.prototype.queryURLParams = function queryURLParams(attr) {
    let self = this,
        obj = {};
    let reg1 = /([^?&=#]+)=([^?&=#]+)/g,
        reg2 = /#([^?&=#]+)/g;
    self.replace(reg1, (_, key, value) => obj[key] = value);
    self.replace(reg2, (_, hash) => obj['HASH'] = hash);

    return typeof attr === "undefined" ? obj : (obj[attr] || '');
}; 

self.replace(reg1, (_, key, value) => obj[key] = value); 回调函数中,每一次匹配到就会执行一次,第一个参数是正则匹配到的完整的字符串,第二个参数是分组1,第三个参数是分组2

URLSearchParams

URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。

ie浏览器不支持,其他浏览器可以直接使用