手写一个提取URL参数的函数

这里提供三种解法:现代 API 法、传统手动解析法,以及将所有参数转为对象的解法。

解法一:现代 API - URL 和 URLSearchParams (强烈推荐)

这是目前浏览器原生支持的最好用的方法,能够轻松满足“获取参数”和“获取域名”的需求。

js
1234567891011121314151617181920
function getUrlParamModern(urlString, paramName) {
  try{
      const url = new URL(urlString)
      if(paramName === "domain"){
          return url.hostname 
          //如果需要获取主域名,则是
          //var parts = url.hostname.split('.')
          //return parts[parts.length - 1]   (因为有可能是www.baidu.com,也有可能是baidu.com)
      }
      return url.searchParams.get(paramName)
  }catch(error){
      console.log("无效的URL格式")
      return null
  }
}

// 测试用例:
const testUrl = "[https://www.example.com/page?name=%E5%BC%A0%E4%B8%89&age=25](https://www.example.com/page?name=%E5%BC%A0%E4%B8%89&age=25)";
console.log(getUrlParamModern(testUrl, 'domain')); // "[www.example.com](https://www.example.com)"
console.log(getUrlParamModern(testUrl, 'name'));   // "张三" (自动解码了)

解法二:传统手动拆解法(用到 decodeURIComponent)

js
12345678910111213141516171819202122232425262728293031323334
function getUrlParamManual(urlString, paramName) {
  // 粗略获取域名的方法:使用正则截取
  if (paramName === 'domain') {
    const domainMatch = urlString.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/im);
    return domainMatch ? domainMatch[1] : null;
  }

  // 1. 找到问号 ? 的位置
  const searchIndex = urlString.indexOf('?');
  if (searchIndex === -1) return null; // 没有参数

  // 2. 截取问号后面的部分:"name=%E5%BC%A0%E4%B8%89&age=25"
  const searchString = urlString.substring(searchIndex + 1);
  
  // 去除哈希值 (如果 URL 里有 #hash)
  const cleanSearch = searchString.split('#')[0];

  // 3. 按 & 分割成数组:["name=%E5%BC%A0...", "age=25"]
  const paramsArray = cleanSearch.split('&');

  // 4. 遍历查找
  for (let i = 0; i < paramsArray.length; i++) {
    const pair = paramsArray[i].split('=');
    const key = pair[0];
    
    if (key === paramName) {
      // 找到了!使用 decodeURIComponent 解码中文和特殊字符
      // 如果没有等号后面的值,默认返回空字符串,否则返回解码后的值
      return pair[1] ? decodeURIComponent(pair[1]) : '';
    }
  }
  
  return null; // 没找到该参数
}

解法三:将所有参数转换为对象(实战常用法)

利用 ES6+ 现代语法(代码极简)

js
12345678910
function getAllParamsToObjModern(urlString) {
  try {
    const url = new URL(urlString);
    // Object.fromEntries 可以把键值对列表转换成一个对象
    // url.searchParams.entries() 产出如: [['name', '张三'], ['age', '25']]
    return Object.fromEntries(url.searchParams.entries());
  } catch (error) {
    return {};
  }
}