URL参数的解析和管理最实用方法-URLSearchParams

6,846 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

前言

解析页面url链接参数与拼接接口请求url链接参数,这两个是前端开发者在工作中最长使用的操作之一。很多信息是通过页面链接的后缀参数传递的,开发者需要先获取到参数才能判断下一步的操作。相信很多开发者都是自己写函数来解析参数,其实浏览器早就内置了一个很好用的链接参数操作工具URLSearchParams,接下来说说自写的解析函数与URLSearchParams的用法。

1. 自写的解析函数函数

我们先看看平时我们自己写,是怎么写的。代码如下:

/*
  url 		  String   可选参数, url地址
  OneKey 	  String   可选参数, 获取当前网址指定参数
  Delete_key  Array    可选参数, 过滤指定参数
*/
const getUrlData = function (url,OneKey,Delete_key=[]){
  if(!url)url = window.location.search;
  var url_l = url.split('?')[1];
  var url_ll = url_l.split('&'),obj ={};
  url_ll.forEach((item,idx)=>{
    var key = item.split('=')[0];
    var val = item.split('=')[1];
    if(Delete_key.indexOf(key)==-1) obj[key] = val;
  })
  if(OneKey&&url_l.indexOf(OneKey))return obj[OneKey];
  return obj;
};

// 调用
var paramsString = 'q=URLUtils.searchParams&topic=api';

// 获取整个对象
console.log(getUrlData(paramsString)) // {q: 'URLUtils.searchParams', topic: 'api'}
// 获取某个属性
console.log(getUrlData(paramsString, 'topic')) // 'api'

上面就是我们平时写的解析url参数的方法最简单的代码了。那么接下来我们来看看URLSearchParams的

2. URLSearchParams

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

2.1.语法

其实例对象的用法和Set数据结构类似。实例对象本身是可遍历对象。但是不是遍历器。

var paramsString = 'q=URLUtils.searchParams&topic=api';
var searchParams = new URLSearchParams(paramsString);

2.2 实例操作方法

2.2.1 has(key)
searchParams.has('topic'); // true
2.2.2 get(key)
searchParams.get('topic'); // 'api'
2.2.3 getAll(key)

当同一个键值对应多个值时用该方法

searchParams.getAll('topic'); // ['api']
2.2.4 append(key,value)-增加
searchParams.append('test', 'testvalue'); 
// searchParams.toString()变为
// "q=URLUtils.searchParams&topic=api&test=testValue"
2.2.5 delete(key)-删除

会删除所有键值为key的查询参数

searchParams.delete('test'); 
// searchParams.toString()变为
// "q=URLUtils.searchParams&topic=api"
2.2.6 set(key, value) 修改
searchParams.set('q', 'test');
// searchParams.toString()变为
// "q=test&topic=api"
2.2.7 toString()

将实例对象变回字符串的形式

2.3 实例遍历方法

下面的方法调用都返回一个Iterator对象。可以通过调用next()方法遍历对象。

想要获取预想的结果,需要使用扩展运算符。

2.3.1 keys()
[...searchParams.keys()] // ["q","topic"]
2.3.2 value()
[... searchParams.values()] // ["test", "api"]
2.3.3 entries()

因为实例对象本身也是可遍历对象。也可以使用扩展运算符。而且和entries()方法的结果相同。

[... searchParams.entries()] // [["q", "test"],["topic", "api"]]
//遍历自身
[... searchParams] // [["q", "test"],["topic", "api"]]

2.4 应用

2.4.1 实例作为POST方法的请求体

该类型的请求体,浏览器会自动添加请求头:

Content-Type: application/x-www-form-urlencoded;charset=UTF-8

而且,作为请求体的=两侧的数据会被进行URL编码(encodeURIComponent())。

      const data = new URLSearchParams("a=b&c=d");
      fetch('/post',{
        method: 'POST',
        body: data
      }).then((result) => console.log(result))
2.4.2 通过URL的实例对象的searchParams属性获取URLSearchParams实例
const url = new URL(location);
url.searchParams instanceof URLSearchParams // true

兼容性解决

工具好用,但是不可避免的兼容性并没有那么的理想。那我们该怎么办呢?

工欲善其事,必先利其器

url-search-params-polyfill

这是一个专门为URLSearchParams制作的polyfill库。具体的使用方法大家可以参照库的相关说明。在这主要再强调一下,这个库能够解决浏览器的兼容性问题,但是在使用fetch进行请求调用时,我们仍然需要手动去设置ContentType的值。引用该库中给到的一个实例

function myFetch(url, { headers = {}, body }) {
    headers = headers instanceof Headers ? headers : new Headers(headers);
    
    if (body instanceof URLSearchParams) {
        headers.set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    }
    
    fetch(url, {
        headers,
        body
    });
}