JS `URLSearchParams` API:解析与构建 URL 查询参数

各位观众老爷,大家好!今天咱们来聊聊前端开发里一个经常用到,但又容易被忽视的小家伙——URLSearchParams。别看它名字长,用起来可是相当顺手,能帮你轻松玩转 URL 里的查询参数。

开场白:URL 里的小秘密

咱们先来回忆一下,URL 长啥样?通常是这样的:

https://www.example.com/path/to/page?param1=value1&param2=value2&param3=value3

URL 里的问号 ? 后面那一坨,就是我们要重点关注的——查询参数(Query Parameters)。它们以键值对的形式存在,键和值之间用等号 = 连接,多个键值对之间用 & 分隔。

查询参数很重要,它们可以用来传递各种信息,比如搜索关键词、分页信息、筛选条件等等。有了它们,我们才能在网页上实现各种复杂的交互。

主角登场:URLSearchParams 是个啥?

URLSearchParams 是 JavaScript 提供的一个内置 API,专门用来解析和构建 URL 查询参数。你可以把它想象成一个专门处理 URL 查询参数的小工具箱,里面装满了各种好用的工具。

URLSearchParams 的基本用法

  1. 创建 URLSearchParams 对象

    要使用 URLSearchParams,首先要创建一个它的实例。有几种方式可以创建:

    • 直接传入查询字符串:

      const paramsString = "param1=value1&param2=value2&param3=value3";
      const searchParams = new URLSearchParams(paramsString);
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2&param3=value3
    • 传入 URL 对象:

      const url = new URL("https://www.example.com/path/to/page?param1=value1&param2=value2");
      const searchParams = new URLSearchParams(url.search); // 注意:取的是 url.search 部分
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2
    • 传入一个对象:

      const paramsObject = {
          param1: "value1",
          param2: "value2",
          param3: "value3",
      };
      const searchParams = new URLSearchParams(paramsObject);
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2&param3=value3
    • 不传任何参数,创建一个空的 URLSearchParams 对象:

      const searchParams = new URLSearchParams();
      console.log(searchParams.toString()); // 输出: (空字符串)
  2. 常用方法:增删改查

    URLSearchParams 提供了一系列方法,方便我们对查询参数进行增删改查。

    • get(name):获取指定参数的值

      const searchParams = new URLSearchParams("param1=value1&param2=value2");
      const value1 = searchParams.get("param1");
      const value2 = searchParams.get("param2");
      const value3 = searchParams.get("param3"); // 不存在的参数
      
      console.log(value1); // 输出: value1
      console.log(value2); // 输出: value2
      console.log(value3); // 输出: null

      如果参数不存在,get() 方法会返回 null

    • getAll(name):获取指定参数的所有值

      当一个参数出现多次时,getAll() 方法可以获取该参数的所有值,并返回一个数组。

      const searchParams = new URLSearchParams("param1=value1&param2=value2&param1=value3");
      const values = searchParams.getAll("param1");
      
      console.log(values); // 输出: ["value1", "value3"]
    • has(name):判断是否存在指定参数

      const searchParams = new URLSearchParams("param1=value1&param2=value2");
      const hasParam1 = searchParams.has("param1");
      const hasParam3 = searchParams.has("param3");
      
      console.log(hasParam1); // 输出: true
      console.log(hasParam3); // 输出: false
    • set(name, value):设置参数的值

      如果参数已存在,则更新其值;如果参数不存在,则添加该参数。

      const searchParams = new URLSearchParams("param1=value1&param2=value2");
      searchParams.set("param1", "new_value1"); // 更新 param1 的值
      searchParams.set("param3", "value3"); // 添加 param3
      
      console.log(searchParams.toString()); // 输出: param1=new_value1&param2=value2&param3=value3
    • append(name, value):添加参数

      set() 不同,append() 总是添加新的参数,即使该参数已存在。

      const searchParams = new URLSearchParams("param1=value1&param2=value2");
      searchParams.append("param1", "value3"); // 添加新的 param1
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2&param1=value3
    • delete(name):删除指定参数

      const searchParams = new URLSearchParams("param1=value1&param2=value2&param1=value3");
      searchParams.delete("param1");
      
      console.log(searchParams.toString()); // 输出: param2=value2
    • toString():将 URLSearchParams 对象转换为查询字符串

      这个方法非常重要,它可以将 URLSearchParams 对象转换回我们熟悉的查询字符串格式。

      const searchParams = new URLSearchParams();
      searchParams.set("param1", "value1");
      searchParams.set("param2", "value2");
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2
    • sort():对参数进行排序

      按照参数名称的 Unicode 码位顺序对参数进行排序。

      const searchParams = new URLSearchParams("param2=value2&param1=value1&param3=value3");
      searchParams.sort();
      
      console.log(searchParams.toString()); // 输出: param1=value1&param2=value2&param3=value3
  3. 遍历 URLSearchParams 对象

    URLSearchParams 对象是一个可迭代对象,可以使用 for...of 循环或 forEach() 方法进行遍历。

    • for...of 循环:

      const searchParams = new URLSearchParams("param1=value1&param2=value2&param3=value3");
      
      for (const [name, value] of searchParams) {
          console.log(`参数名: ${name}, 参数值: ${value}`);
      }
      // 输出:
      // 参数名: param1, 参数值: value1
      // 参数名: param2, 参数值: value2
      // 参数名: param3, 参数值: value3
    • forEach() 方法:

      const searchParams = new URLSearchParams("param1=value1&param2=value2&param3=value3");
      
      searchParams.forEach((value, name) => {
          console.log(`参数名: ${name}, 参数值: ${value}`);
      });
      // 输出:
      // 参数名: param1, 参数值: value1
      // 参数名: param2, 参数值: value2
      // 参数名: param3, 参数值: value3

URLSearchParams 的应用场景

  • 构建 URL:

    const baseUrl = "https://www.example.com/search";
    const params = {
        q: "javascript",
        page: 2,
        sort: "relevance",
    };
    const searchParams = new URLSearchParams(params);
    const url = `${baseUrl}?${searchParams.toString()}`;
    
    console.log(url); // 输出: https://www.example.com/search?q=javascript&page=2&sort=relevance
  • 解析 URL 中的查询参数:

    const url = "https://www.example.com/search?q=javascript&page=2&sort=relevance";
    const searchParams = new URLSearchParams(new URL(url).search);
    
    const query = searchParams.get("q");
    const page = searchParams.get("page");
    const sort = searchParams.get("sort");
    
    console.log(query); // 输出: javascript
    console.log(page); // 输出: 2
    console.log(sort); // 输出: relevance
  • 处理表单数据:

    当使用 fetchXMLHttpRequest 发送表单数据时,可以使用 URLSearchParams 来格式化数据。

    <form id="myForm">
      <input type="text" name="username" value="JohnDoe">
      <input type="email" name="email" value="[email protected]">
    </form>
    
    <script>
      const form = document.getElementById('myForm');
      form.addEventListener('submit', (event) => {
        event.preventDefault();
    
        const formData = new FormData(form);
        const searchParams = new URLSearchParams(formData);
    
        fetch('/submit', {
          method: 'POST',
          body: searchParams,
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded' // 必须设置 Content-Type
          }
        })
        .then(response => response.json())
        .then(data => console.log(data));
      });
    </script>
  • 在 History API 中使用:

    可以使用 URLSearchParams 来修改 URL,而无需重新加载页面。

    const url = new URL(window.location.href);
    const searchParams = new URLSearchParams(url.search);
    searchParams.set("theme", "dark");
    
    url.search = searchParams.toString();
    history.pushState(null, "", url.toString());

URLSearchParams 的注意事项

  • 编码: URLSearchParams 会自动对参数进行 URL 编码,确保参数值在 URL 中是安全的。例如,空格会被编码为 %20

  • 浏览器兼容性: URLSearchParams 具有良好的浏览器兼容性,几乎所有现代浏览器都支持它。 对于旧版本浏览器,可能需要使用 Polyfill。

  • FormDataURLSearchParams 的区别: FormData 主要用于处理文件上传,而 URLSearchParams 主要用于处理简单的键值对。 如果你需要上传文件,请使用 FormData。如果只需要传递简单的键值对,使用 URLSearchParams 更方便。

URLSearchParams 和手动拼接字符串的对比

以前没有 URLSearchParams 的时候,我们通常会手动拼接查询字符串,就像这样:

const params = {
    param1: "value1",
    param2: "value2",
    param3: "value3",
};

let queryString = "";
for (const key in params) {
    if (params.hasOwnProperty(key)) {
        queryString += `&${key}=${params[key]}`;
    }
}

if (queryString.length > 0) {
    queryString = "?" + queryString.substring(1); // 去掉第一个 &
}

console.log(queryString); // 输出: ?param1=value1&param2=value2&param3=value3

这种方式不仅繁琐,而且容易出错。例如,需要手动进行 URL 编码,需要处理第一个 & 符号等等。而使用 URLSearchParams,这些问题都可以轻松解决。

功能 手动拼接字符串 URLSearchParams
代码量 较多 较少
可读性 较差 较好
易错性 较高 较低
URL 编码 需要手动处理 自动处理
浏览器兼容性 良好 良好

高级技巧:利用 URLSearchParams 解析复杂的 URL

假设你有一个复杂的 URL,包含多个参数,有些参数还重复出现,你需要提取其中的特定参数。URLSearchParams 可以帮你轻松实现。

const url = "https://www.example.com/search?q=javascript&page=2&sort=relevance&filter=new&filter=popular";
const searchParams = new URLSearchParams(new URL(url).search);

const query = searchParams.get("q"); // 获取搜索关键词
const page = parseInt(searchParams.get("page"), 10); // 获取页码,并转换为数字
const filters = searchParams.getAll("filter"); // 获取所有过滤器

console.log(query); // 输出: javascript
console.log(page); // 输出: 2
console.log(filters); // 输出: ["new", "popular"]

总结

URLSearchParams 是一个非常实用的 API,可以帮助我们轻松地解析和构建 URL 查询参数。它具有代码简洁、可读性好、易于维护等优点。在前端开发中,掌握 URLSearchParams 的用法,可以提高开发效率,减少出错的概率。

希望今天的讲座能帮助大家更好地理解和使用 URLSearchParams。记住,熟练掌握这些小工具,才能在前端开发的道路上越走越远!

各位,下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注