JavaScript获取URL参数的几种方法

前言

在前端开发中,处理URL参数是一个常见的任务,尤其是在没有框架支持的情况下。虽然许多框架提供了方便的方法来获取URL参数,但有时我们需要依赖原生JavaScript来完成这个任务。这也是面试中经常出现的问题之一。今天让我们一起来探讨如何利用原生JavaScript来获取URL参数值。
 

获取方法总结

原生JS获取URL链接参数的方法有好几种,我们一起来学习一下常见的几种。

1.使用正则表达式

2.利用a标签内置方法

3.利用split分割方法

4.使用URLSearchParams方法

具体实现

方法一: 正则表达式

function queryURLParams(url, paramName) {// 正则表达式模式,用于匹配URL中的参数部分。正则表达式的含义是匹配不包含 ?、&、= 的字符作为参数名,之后是等号和不包含 & 的字符作为参数值let pattern = /([^?&=]+)=([^&]+)/g;let params = {};// match用于存储正则匹配的结果let match;// while 循环和正则表达式 exec 方法来迭代匹配URL中的参数while ((match = pattern.exec(url)) !== null) {// 在字符串url中循环匹配pattern,并对每个匹配项进行解码操作,将解码后的键和值分别存储在key和value变量中let key = decodeURIComponent(match[1]);let value = decodeURIComponent(match[2]);if (params[key]) {if (Array.isArray(params[key])) {params[key].push(value);} else {params[key] = [params[key], value];}} else {// 参数名在 params 对象中不存在,将该参数名和对应的值添加到 params 对象中params[key] = value;}}if (!paramName) {// 没有传入参数名称, 返回含有所有参数的对象paramsreturn params;} else {if (params[paramName]) {return params[paramName];} else {return '';}}
}let url = "http://www.baidu.com?name=elephant&age=25&sex=male&num=100&name=lion";
console.log(queryURLParams(url)); // 返回所有参数对象
console.log(queryURLParams(url, 'name')); // 返回参数名为 'name' 的所有值
console.log(queryURLParams(url, 'age')); // 返回参数名为 'age' 的值
console.log(queryURLParams(url, 'color')); // 返回""

正则表达式解释: 

  • ([^?&=]+):这部分是一个捕获组,表示匹配不包含 ?&= 的任意字符的一个或多个,即匹配参数名部分。
  • =:表示匹配参数名和参数值之间的等号。
  • ([^&]+):这部分也是一个捕获组,表示匹配不包含 & 的任意字符的一个或多个,即匹配参数值部分。
  • g:表示使用全局匹配模式,即匹配目标字符串中所有符合模式的部分。

方法二: 利用a标签

a标签内置的方法能够快速且方便地获取URL参数,

它的原理主要就是利用了a标签得到一些内置属性,如href、hash、search等属性。

考虑到URL中的哈希部分,在函数queryURLParams(url)中,会检查URL中的哈希部分是否存在,如果存在则将哈希值存储到参数对象中,并将属性名设置为"HASH"。这样在返回的参数对象中,如果URL中有哈希部分,就可以通过"HASH"来访问哈希值。

let URL = "http://www.baidu.com?name=elephant&age=25&sex=male&num=100#smallpig"function queryURLParams(url) {// 1.创建a标签let link = document.createElement('a');link.href = url;let searchUrl = link.search.substr(1); // 获取问号后面字符串let hashUrl = link.hash.substr(1); // 获取#后面的值let obj = {}; // 声明参数对象// 2.向对象中进行存储hashUrl ? obj['HASH'] = hashUrl : null; // #后面是否有值let list = searchUrl.split("&");for (let i = 0; i < list.length; i++) {let arr = list[i].split("=");obj[arr[0]] = arr[1];}return obj;}console.log(queryURLParams(URL))

上段代码中先创建了一个a标签,然后就可以根据a标签的属性分别得到url的各个部分了,这其实和Vue的路由跳转获取参数有点类似。

1. 将传入的URL赋值给 `<a>` 标签的 `href` 属性的目的是利用浏览器提供的原生 API 来帮助实现 URL 参数的解析。通过将URL赋值给 `<a>` 标签的 `href` 属性,浏览器会自动解析这个URL,包括提取其中的协议、主机、路径、查询参数等各个部分,从而方便我们对这个URL进行进一步的操作。

2. 通过`link.search.substr(1)`和`link.hash.substr(1)`可以获取URL中问号后面的字符串和`#`后面的值,是因为浏览器在解析URL后会将这些信息存储在`<a>`标签对象的对应属性中。具体来说:
   - `link.search` 包含了 URL 中问号后面的部分(即查询参数部分)。
   - `link.hash` 包含了 URL 中`#`后面的部分(即片段部分)。
   - 使用`substr(1)`是为了去掉字符串中的问号或`#`字符,只留下真正的参数内容或片段内容。
 

方法三: split分割法

这种方法利用了split可以以某个字符讲字符串分割为数组的特点,巧妙地将各个参数分割出来。

function getUrlParams(url, paramName) {// 从 URL 中提取查询参数部分const queryString = url.split('?')[1];// 如果没有查询参数,返回空对象if (!queryString) {return {};}// 处理带有 hash 地址的情况const hashIndex = queryString.indexOf('#');if (hashIndex !== -1) {queryString = queryString.substring(0, hashIndex);}// 将查询参数字符串解析为键值对const queryParams = {};queryString.split('&').forEach(param => {const [key, value] = param.split('=');// 如果值已经存在,则将其转换为数组存储if (queryParams[key]) {if (Array.isArray(queryParams[key])) {queryParams[key].push(decodeURIComponent(value));} else {queryParams[key] = [queryParams[key], decodeURIComponent(value)];}} else {queryParams[key] = decodeURIComponent(value);}});// 如果没有指定参数名称,则返回包含所有查询参数的对象if (!paramName) {return queryParams;}// 如果指定了参数名称if (queryParams[paramName]) {return queryParams[paramName];} else {// 参数不存在,返回空字符串return '';}
}// 示例 URL
const url = 'https://example.com?name=John&age=30&name=Jane&gender=male';
const urlWithHash = 'http://xxx.com/#/operations/app?name=John&age=30&name=Jane&gender=male';console.log(getUrlParams(url)); 
// 输出: { name: ['John', 'Jane'], age: '30', gender: 'male' }console.log(getUrlParams(url, 'name'));
// 输出: ['John', 'Jane']console.log(getUrlParams(url, 'age'));
// 输出: '30'console.log(getUrlParams(url, 'city'));
// 输出: ''console.log(getUrlParams(urlWithHash)); 
// 输出: { name: ['John', 'Jane'], age: '30', gender: 'male' }
关于hash地址部分

在处理 URL 查询参数时,通常情况下不需要处理 hash 地址部分。

Hash 地址通常用于客户端路由或页面内导航,一般不会包含查询参数信息。

但在某些情况下,可能需要处理带有 hash 地址的 URL,例如:

1. 当需要从 URL 中提取查询参数时,如果 URL 中的查询参数部分后面紧跟着 hash 地址(如 `http://example.com/page?name=John#section2`),需要排除 hash 部分以确保正确提取查询参数。

2. 如果要监听 hash 地址的变化,并根据不同的 hash 地址执行不同的逻辑(如单页面应用路由器),则需要处理 hash 地址的改变并做出响应。 总的来说,在处理 URL 查询参数时一般不需要处理 hash 地址部分,但在特定情况下需要注意并处理。

方法四: URLSearchParams

URLSearchParams方法能够让我们非常方便的获取URL参数,但是存在一定的兼容性问题,官网的解释如下:

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

该接口提供了非常的的方法让我们来处理URL参数,这里我们只介绍如何获取URL参数值,更加详细的使用方法大家可以参考官网。

 let URL = "http://www.baidu.com?name=elephant&age=25&sex=male&num=100"function queryURLParams(URL) {let url = URL.split("?")[1];const urlSearchParams = new URLSearchParams(url);const params = Object.fromEntries(urlSearchParams.entries());return params}console.log(queryURLParams(URL))

这里我们基本上只用了两行主要代码就实现了参数的解析。需要注意的是urlSearchParams.entries()返回的是一个迭代协议iterator,所以我们需要利用Object.fromEntries()方法将把键值对列表转换为一个对象。

关于迭代协议,大家可以参考官网:迭代协议

总结:

这里介绍了四种方法来实现URL链接参数值的解析,其中使用最为广泛的应该当属split分割法。总的来说,了解和掌握这些方法可以帮助前端开发者更有效地处理URL参数,从而提升开发效率和应对面试中可能出现的相关问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51571.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LRTimelapse Pro 7.0 安装教程

软件介绍 LRTimelapse Pro (LRT) 是一款专业的延迟摄影编辑渲染工具&#xff0c;具有高清输出、简单易用、无缝转换等特点。是非常强大的一款延迟摄影工具&#xff01;LRTimelapse Pro可以将您的影片提升一个水准。 程序可以配合 Adobe Lightroom, Adobe Camera RAW 和 Adobe…

2024年孝感中级职称报名开始了吗?

2024年孝感中级职称申报终于开始了&#xff0c;之前参加过水测的小伙伴们&#xff0c;开始准备评审了 2024年孝感本批次申报时间&#xff1a;中级、初级职称网上申报时间:2024年8月1日至8月31日。 注意&#xff1a;个人通过“湖北省职称评审管理信息系统”申报&#xff0c;须先…

Llama 3.1 重磅发布,登顶开源大模型王座!

7月23日&#xff0c;Meta正式发布迄今为止最强大的开源模型——Llama 3.1 405B&#xff0c;同时发布了全新升级的Llama 3.1 70B和8B模型。 Meta在正式发布里也附上了长达92页的论文《The Llama 3 Herd of Models》&#xff0c;揭示了Llama 3模型的技术和训练细节。 论文地址&am…

Jacoco 单元测试配置

前言 编写单元测试是开发健壮程序的有效途径&#xff0c;单元测试写的好不好可以从多个指标考量&#xff0c;其中一个就是单元测试的覆盖率。单元测试覆盖率可以看到我们的单元测试覆盖了多少代码行、类、分支等。查看单元测试覆盖率可以使用一些工具帮助我们计算&#xff0c;…

GLSL教程 第12章:现代GLSL特性

目录 12.1 现代OpenGL的特性和GLSL的兼容性 1.1 OpenGL版本及其影响 1.2 GLM与GLSL的兼容性 12.2 使用GLSL的新特性进行开发 2.1 Tessellation Shader 2.2 Compute Shader 2.3 多重渲染目标&#xff08;MRT&#xff09; 12.3 着色器的兼容性和移植性问题 3.1 兼容性问…

图解RocketMQ之生产者如何进行消息重试

大家好&#xff0c;我是苍何。 上一篇留了一个小问题&#xff0c;如果消费者出现异常&#xff0c;消费某一条消息失败&#xff0c;这时候 RocketMQ 会怎么处理呢&#xff1f; 你可能会用你聪明绝顶的脑袋瓜子想&#xff0c;苍何你是不是傻&#xff0c;失败了肯定重试啊&#…

单据新增,限制单据栏位的录入值,设置过滤条件

希望通过开发实现 单据头的组织栏位,只能选择101开头的组织,实现的效果如下: 代码如下: using Kingdee.BOS.Util; using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using System.ComponentModel;namespace cux.button.test {…

基于opencv的人脸识别(实战)

前言 经过这几天的学习&#xff0c;我已经跃跃欲试了&#xff0c;相信大家也是&#xff0c;所以我决定自己做一个人脸识别程序。我会把自己的思路和想法都在这篇博客内讲清楚&#xff0c;大家可以当个参考&#xff0c;&#x1f31f;仅供学习使用&#x1f31f;。 &#x1f31f…

分享10个好用的论文编辑服务/平台

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 如果您对自己的学术写作能力存在怀疑&#xff0c;论文编辑服务/平台或许能提供帮助。为了帮助您做出更好的选择&#xff0c;今天的分享我们列出了2024年“全网”最好用的10个论文编辑服…

怎么样建设数字化车间?

建设数字化车间是一个综合性的过程&#xff0c;旨在通过现代信息技术、智能设备和自动化技术对车间进行优化改造&#xff0c;提高生产效率和产品质量。以下是一些关键步骤和要点&#xff0c;用于指导数字化车间的建设&#xff1a; 一、明确建设目标和需求 分析现状&#xff1…

【轨物方案】开关柜在线监测物联网解决方案

随着物联网技术的发展&#xff0c;电力设备状态监测技术也得到了迅速发展。传统的电力成套开关柜设备状态监测方法主要采用人工巡检和定期维护的方式&#xff0c;这种方法不仅效率低下&#xff0c;而且难以保证设备的实时性和安全性。因此&#xff0c;基于物联网技术的成套开关…

2024上海国际嵌入式展回顾 | 聚焦嵌入式开发中的合规性工具、项目管理工具、版本迭代工具应用

日前&#xff0c;龙智携嵌入式开发及管理解决方案亮相2024上海国际嵌入式展&#xff08;embedded world China 2024&#xff09;。展会期间&#xff0c;我们对话了多位龙智资深DevSecOps顾问及技术支持专家&#xff0c;就嵌入式开发与管理领域的最新趋势、工具选择以及DevSecOp…

数论与代数几何问题的分类

数论与代数几何作为数学的两个重要分支&#xff0c;各自拥有广泛的研究领域和问题分类。以下是对这两个领域问题分类的概述&#xff1a; 数论问题分类 数论是研究整数的性质的学科&#xff0c;它涵盖了多个方面的问题。按研究方法来看&#xff0c;数论大致可分为初等数论和高…

Inno setup pascal编码下如何美化安装界面支持带边框,圆角,透明阴影窗口

inno setup自带的安装界面太老套了&#xff0c;如何实现类似网易&#xff0c;微信那种带界面的安装&#xff1f;一般有两种思路&#xff1a;提供一个单独的下载器&#xff0c;然后通过下载器将你用innosetup 打包后的软件下载下来&#xff0c;然后&#xff0c;静默安装这个包&a…

CPU、GPU等处理器介绍

CPU、GPU、IPU、NPU、TPU、LPU、MCU、MPU、SOC、DSP、FPGA、ASIC、GPP、ECU、_c_limengshi138392-GitCode 开源社区

Mybatis-Plus-常用的注解:@TableName、@TableId、@TableField、@TableLogic

1、TableName 经过之前的测试&#xff0c;在使用MyBatis-Plus实现基本的CRUD时&#xff0c;我们并没有指定要操作的表&#xff0c;只是在Mapper接口继承BaseMapper时&#xff0c;设置了泛型User&#xff0c;而操作的表为user表由此得出结论&#xff0c;MyBatis-Plus在确定操作…

Python:随机数、随机选择的应用

step1:导入 导入的random相当于是创建了random文件里的的一个对象 import random random() 产生0~1随机数 randint(a,b)产生a~b的整数 闭区间&#xff0c;可以取到a,b random.choice(touple_name)从touple_name&#xff08;数组、列表..&#xff09;中随机选择元素 import rand…

技术周总结 2024.07.22~07.28周日(Java Tidb Mysql)

文章目录 一、 07.23 周二1.1&#xff09;问题01&#xff1a;下面的java代码会发生NPE吗&#xff1f;String aa "ss: "; String bb null; aa bb;解释完整示例输出总结 1.2&#xff09;问题02&#xff1a;Spring注解ControllerAdvice 具体的使用方法1.3) 问题03&am…

Java人力资源招聘社会校招类型招聘小程序

✨&#x1f4bc;【职场新风尚&#xff01;解锁人力资源招聘新神器&#xff1a;社会校招类型招聘小程序】✨ &#x1f393;【校招新体验&#xff0c;一键触达梦想企业】&#x1f393; 还在为错过校园宣讲会而懊恼&#xff1f;别怕&#xff0c;社会校招类型招聘小程序来救场&am…

日常进度提醒

今日进行学习的时联合和枚举&#xff0c;加油&#xff01;