使用新的 API 获取 url 中的参数

背景

今天在地铁上刷到一个面试视频,博主提问:获取url中参数的新方法?

关于这个问题,平时在项目中都是高频使用,按照以前jq时代,那就是原生自己造个轮子就用了,后面有了框架,基本都是使用别人造好的轮子,直接拿来就用,也就很少去考虑这些。

本着不了解有兴趣,所以就趁着午休时间学习了解一下,顺便把以前的方式也给复习了一遍。

示例地址:

http://localhost:8887/fill?calcUnitId=290&checkType=1&cycleType=BY_YEAR&orgId=10018066&pageType=1&preSubTaskId&smModelId=666&status=%E6%9C%AA%E5%A1%AB%E6%8A%A5&subtaskId=47957&taskName=2025y&timestamp=1704681001789

获取参数(旧API)

采用以前的方式获取参数那就简单了,总的来说的,可以分为几个步骤

采用上面的示例逐步进行分析,下面的步骤将每一步获取到的结果都进行了打印,便于对应学习。

  • 步骤一
    以 ? 为界限进行分割, 拿到所有的参数

    const url_split = url.split('?');
    console.log('url_split::', url_split);
    
    const params = url_split[1];
    conole.log('params::', params)
    
  • 步骤二
    以 & 为界限分割,将每个参数以 key = value 的形式展现得到一个数组

    const url_split = url.split('?');
    console.log('url_split::', url_split);
    
    const params = url_split[1];
    console.log('params::', params);
    
    // 新增
    var paramsKeyValue = params.split('&');
    console.log('paramsKeyValue::', paramsKeyValue);
    
  • 步骤三
    创建 params 对象,便于数据拿取

    const url_split = url.split('?');
    console.log('url_split::', url_split);
    
    const params = url_split[1];
    console.log('params::', params);
    
    const paramsKeyValue = params.split('&');
    console.log('paramsKeyValue::', paramsKeyValue);
    
    // 新增
    const params = {};
    
  • 步骤四
    循环得到的数组 paramsKeyValue,再次将每一项以 = 进行分割;
    其实步骤三和步骤四可以归属为一步,这里只是将其细分了一下。
    如果确定要进行函数封装,那么建议将步骤三提到步骤一前面,便于函数返回结果;

    const url_split = url.split('?');
    console.log('url_split::', url_split);
    
    const params = url_split[1];
    console.log('params::', params);
    
    const paramsKeyValue = params.split('&');
    console.log('paramsKeyValue::', paramsKeyValue);
    
    const params = {};
    
    // 新增
    paramsKeyValue.forEach((item) => {
    	const [key, value] = item.split('=');
    	params[key] = value;
    });
    
    console.log('params::', params);
    
    

到此就算获取到完整的参数对象了,整体不复杂,里面呢关于数组循环获取值这些完全可以再次进行优化处理,使其更加的严谨健壮,可以从一下方面进行优化,比如:

  • 地址是否存在,
  • 数组的长度判断,
  • 公共函数封装,
  • 获取对象中具体的某个值,
  • 如果用上ts 那么把数据类型给加上,
  • 是否需要缓存

  • 以上这些都是作为优化考虑的点;

获取参数(新API)

针对上面提到的优化点,其实在官网已经给提供了新的API【URLSearchParams】。

下面是对他的一些描述,大家看看就好,最好是自己动手敲上一遍。

URLSearchParams 定义

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

构造函数

URLSearchParams() 返回一个 URLSearchParams 对象

var params = new URLSearchParams(url);
console.log('params::', params)

从返回的 URLSearchParams 对象 的原型上可以看到有如下方法:
在这里插入图片描述
接下来就一一打印输出看看,每个方法都是怎使用的。

方法

该接口不继承任何属性。

  • 基础使用
    根据MDN所说,使用 for ( const item of params) {} 打印看看具体都是些什么内容。

    var params = new URLSearchParams(url);
    console.log('params::', params)
    
    // 新增
    for (const item of params) {
        console.log('atrrs22222222:key--', item)
    };
    
    // 输出如下结果:
    /*
    VM13196:43 atrrs22222222:key-- (2) ['http://localhost:8887/fill?calcUnitId', '290']
    VM13196:43 atrrs22222222:key-- (2) ['checkType', '1']
    VM13196:43 atrrs22222222:key-- (2) ['cycleType', 'BY_YEAR']
    VM13196:43 atrrs22222222:key-- (2) ['orgId', '10018066']
    VM13196:43 atrrs22222222:key-- (2) ['pageType', '1']
    VM13196:43 atrrs22222222:key-- (2) ['preSubTaskId', '']
    VM13196:43 atrrs22222222:key-- (2) ['smModelId', '666']
    VM13196:43 atrrs22222222:key-- (2) ['status', '未填报']
    VM13196:43 atrrs22222222:key-- (2) ['subtaskId', '47957']
    VM13196:43 atrrs22222222:key-- (2) ['taskName', '2025y']
    VM13196:43 atrrs22222222:key-- (2) ['timestamp', '1704681001789']
    */
    

    从打印的结果这么一看好像是一个二维的数组。

    但是这里要注意一下,这里有一点不一样的地方,请看输出第一项,他的这个key('http://localhost:8887/fill?calcUnitId')居然包含了问号及前面所有域名地址信息,这个就不合理了对吧。

    那这是为什么呢?

    原因很简单哈,因为这里使用的url 是一个完整的地址 + 参数,如果在实际项目中则采用 window.location.search 去获取参数,然后再给放到 new URLSearchParams() 里面作为参数,这样解析出来后就不带前面的域名地址信息。

  • URLSearchParams.get()
    获取指定搜索参数的第一个值。

    var params = new URLSearchParams(url);
    console.log('params::', params.get('参数名'));
    
  • URLSearchParams.getAll()
    获取指定搜索参数的所有值,返回是一个数组。

    var params = new URLSearchParams(url);
    console.log('params::', params.getAll('参数名'));
    
    // 例:
    var url = '?calcUnitId=001&calcUnitId=290&checkType=1'
    
    var params = new URLSearchParams(url);
    console.log('atrrs: ', params.getAll('calcUnitId'))
    
    
    // VM13388:5 atrrs:  (2) ['001', '290']
    

    这个 getAll() 感觉有些鸡肋哈,不知道会在什么情况下会使用,如果有懂的同学,可以评论区多多留言。

  • URLSearchParams.keys()
    返回iterator 此对象包含了键/值对的所有键名。

    var params = new URLSearchParams(url);
    console.log('params::', params.keys());
    
    for (const item of params.keys()) {
        console.log('item:', item)
    }
    
  • URLSearchParams.values()
    返回iterator 此对象包含了键/值对的所有值。

    var params = new URLSearchParams(url);
    console.log('params::', params.values());
    
    for (const item of params.values()) {
        console.log('item:', item)
    }
    
  • URLSearchParams.entries()
    返回一个 iterator (迭代器) 可以遍历所有键/值对的对象。

    var params = new URLSearchParams(url);
    console.log('params::', params.entries());
    
    // 打印结果:params:: URLSearchParams Iterator {}
    // 打印结果中明确的指出了迭代器,既然如此,那就采用循环把每一项都给打印出来
    

    关于迭代器相关知识讲起来也是可以单独写一篇文章了,并且网上也比较多,都比较全面,所以就自行GPT,这里就不再过多赘述。

    获取每一项数据:

    for (const item of params.entries()) {
        const [key, value] = item;
        console.log('atrrs:  ' + item + ',       value:' + [key, value])
    }
    
    /*
    VM13266:9 atrrs:  calcUnitId,290,       value:calcUnitId,290
    VM13266:9 atrrs:  checkType,1,       value:checkType,1
    VM13266:9 atrrs:  cycleType,BY_YEAR,       value:cycleType,BY_YEAR
    VM13266:9 atrrs:  orgId,10018066,       value:orgId,10018066
    VM13266:9 atrrs:  pageType,1,       value:pageType,1
    VM13266:9 atrrs:  preSubTaskId,,       value:preSubTaskId,
    VM13266:9 atrrs:  smModelId,666,       value:smModelId,666
    VM13266:9 atrrs:  status,未填报,       value:status,未填报
    VM13266:9 atrrs:  subtaskId,47957,       value:subtaskId,47957
    VM13266:9 atrrs:  taskName,2025y,       value:taskName,2025y
    VM13266:9 atrrs:  timestamp,1704681001789,       value:timestamp,1704681001789
    */
    
  • URLSearchParams.set()
    设置一个搜索参数的新值,假如原来有多个值将删除其他所有的值。

    1. 示例1
      var url = '?calcUnitId=001&calcUnitId=290&checkType=1'
      
      var params = new URLSearchParams(url);
      params.set('checkType', 124)
      
      for (const item of params.entries()) {
          console.log('item:', item)
      }
      
      /*
      VM13715:9 item: (2) ['calcUnitId', '001']
      VM13715:9 item: (2) ['calcUnitId', '290']
      VM13715:9 item: (2) ['checkType', '124']
      */
      
    2. 示例2
      var url = '?calcUnitId=001&calcUnitId=290&checkType=1'
      
      var params = new URLSearchParams(url);
      params.set('calcUnitId', 124)
      
      for (const item of params.entries()) {
          console.log('item:', item)
      }
      
      /* 
      VM13718:9 item: (2) ['calcUnitId', '124']
      VM13718:9 item: (2) ['checkType', '1']
      */
      
  • URLSearchParams.sort()
    按键名排序。

    var params = new URLSearchParams(url);
    console.log('atrrs: ', params.sort())
    
  • URLSearchParams.toString()
    返回搜索参数组成的字符串,可直接使用在 URL 上。

    var params = new URLSearchParams(url);
    console.log('atrrs: ', params.toString())
    
    // atrrs:  calcUnitId=001&calcUnitId=290&checkType=1&cycleType=BY_YEAR&orgId=10018066&pageType=1&preSubTaskId=&smModelId=666&status=%E6%9C%AA%E5%A1%AB%E6%8A%A5&subtaskId=47957&taskName=2025y&timestamp=1704681001789
    
  • URLSearchParams.append(key,value)
    插入一个指定的键/值对作为新的搜索参数。

    var params = new URLSearchParams(url);
    
    // 新增
    params.append('aa', 1111);
    
    for (const item of params.keys()) {
        console.log('item:', item)
    }
    
    /*
    	VM13590:9 item: calcUnitId
    	VM13590:9 item: checkType
    	VM13590:9 item: cycleType
    	VM13590:9 item: orgId
    	VM13590:9 item: pageType
    	VM13590:9 item: preSubTaskId
    	VM13590:9 item: smModelId
    	VM13590:9 item: status
    	VM13590:9 item: subtaskId
    	VM13590:9 item: taskName
    	VM13590:9 item: timestamp
    	VM13590:9 item: aa    // 新添加的aa
    */
    
  • URLSearchParams.delete(key)
    从搜索参数列表里删除指定的搜索参数及其对应的值。

    var params = new URLSearchParams(url);
    
    // 删除
    params.delete('aa');
    
  • URLSearchParams.has()
    返回 Boolean 判断是否存在此搜索参数。

    var params = new URLSearchParams(url);
    console.log('params::', params.has('参数名'));
    

特殊情况

URLSearchParams 构造函数不会解析完整 URL,但是如果字符串起始位置有 ? 的话会被去除。

上面这句话直白的翻译就是:

如果参数 ?calcUnitId=290&checkType=1&cycleType=BY_YEAR&orgId=10018066&pageType=1&preSubTaskId&smModelId=666&status=%E6%9C%AA%E5%A1%AB%E6%8A%A5&subtaskId=47957&taskName=2025y&timestamp=1704681001789' 是这种前面带 ? 的,在使用的时候会自动去掉 ?

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值