为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript中操作URL的那些事儿

Joe Attardi撰写✏️

URL是任何web应用的重要组成部分。如果你的应用向API发出请求,那么确保构建正确的URL对于这些请求来说非常重要。URL API在所有现代浏览器中都得到了支持,它提供了一种方便解析和操作URL的方式。它使得访问和操作URL的各个部分变得简单。

了解 URL 的结构

请看如下 URL:

https://example.com/api/search?query=foo&sort=asc#results

这个网址由以下部分构成:

  • 协议: https
  • 主机名: example.com
  • 路径: /api/search
  • 查询参数: ?query=foo&sort=asc
  • 锚: #results

使用现代 JavaScript,我们可以解析网址并按需提取不同部分。

解析网址

在旧版本浏览器中,在 URL API 可用之前,开发人员通常会利用 <a> 元素来解析 URL。此元素能够进行一些基本的 URL 解析。例如,你可以这样从 URL 中提取查询字符串:

    // 获取 URL 中的查询字符串
    function getQueryString(url) {
      const link = document.createElement('a');
      link.href = url;
      return url.search;
    }

进入全屏 退出全屏

不过,这种方法也有一些不足之处:

  • 它需要浏览器环境,这在Node.js这样的环境中是行不通的
  • 它也没有错误处理——如果href属性中的URL无效,也不会报错

你也可以用正则表达式把URL的不同部分解析出来,但这会很繁琐且容易出错。

使用 URL API 来解析 URL 非常简单。只需将您想要解析的 URL 传递给 URL 构造函数。如果 URL 字符串有效的话,您将得到一个 URL 对象,该对象包含了 URL 各个部分。

    const url = new URL('https://example.com/api/search?query=foobar');
    console.log(url.host); // 示例.com
    console.log(url.pathname); // /api/搜索
    console.log(url.search); // ?查询=foobar

进入全屏,退出全屏

解析查询字符串参数

例如,我们可以解析URL中的查询字符串参数来获取用户信息。

你可以通过两种方式获取 URL 中的查询字符串:

  • search 属性,它包含完整的查询字符串(包括 ? 字符在内)
  • searchParams 属性,它是 URLSearchParams 对象

如果你对查询字符串中的某个参数感兴趣,你可以使用它的 get 方法通过名称获取该参数。

const url = new URL('https://example.com/api/search?query=foobar&maxResults=10');
console.log(url.searchParams.get('query')); // 搜索查询 "foobar".
console.log(url.searchParams.get('maxResults')); // 最大结果数量 "10".

全屏模式,按ESC退出

如果有多个相同名称的参数,你可以用 getAll 获取一个包含所有该名称值的数组:

    const url = new URL('https://example.com/api/search?tag=标签1&tag=标签2&tag=标签3');
    console.log(url.searchParams.getAll('tag')); // ['标签1', '标签2', '标签3']

全屏;退出全屏

建立查询内容

手动构建查询字符串可能很棘手,尤其是当查询参数包含需要转义的特殊字符时。例如,如果查询参数需要包含一个 & 字符,你得把它编码成 %26,在这种情况下,你需要使用 encodeURIComponent 函数。

    let queryString = 'foo=bar';
    queryString += '&baz=qux';
    queryString += '&tag=' + encodeURIComponent('one&two');
    console.log(queryString); // 输出:foo=bar&baz=qux&tag=one%26two

全屏模式 退出全屏

你可以更安全地通过使用 URLSearchParams (URL搜索参数对象) 来构建查询字符串。

    const params = new URLSearchParams();
    params.append('foo', 'bar');
    params.append('baz', 'qux');
    params.append('tag', 'one&two');
    console.log(params.toString()); // 输出:foo=bar&baz=qux&tag=one%26two

进入全屏 退出全屏

使用 URLSearchParams 的好处主要有:

  • 你不必担心这些用于分隔参数的 & 字符。
  • 你不需要对参数值进行 URL 编码
  • 你不需要使用字符串拼接
如何迭代遍历参数

如果没有 URLSearchParams 对象的话,遍历查询字符串中的参数会变得稍微复杂一些。你需要多次拆分字符串来实现,首先是拆分成键值对,然后再分别拆分键和值。

function 列出查询参数(queryString) {
  queryString.split('&').forEach(param => {
    const [key, value] = param.split('=');
    console.log(`${key}: ${value}`);
  });
}

// 控制台输出每个查询参数的键值对

请点击进入全屏,退出全屏

要是参数可能包含编码字符,这样的话你也得把它们解码一下。

    function listQueryParams(queryString) {
      // 解析查询字符串,打印每个参数的键值对
      queryString.split('&').forEach(param => {
        const [key, value] = param.split('=');
        console.log(`${key}: ${decodeURIComponent(value)}`);
      });
    }

切换到全屏模式 退出全屏

相反地,你可以使用 URLSearchParamsentries 方法来遍历这些键值对。(括号内的内容可以保持英文原样,因为它们是代码)

    function 列出查询参数(queryString) {
      const 参数 = new URLSearchParams(queryString);
      参数.entries().forEach(([键, 值]) => console.log(`${键}: ${值}`));
      // 列出查询字符串中的所有参数键值对
    }

全屏显示 退出全屏

构建完整的网址

这里有一个使用基本URL和一些查询参数来构建URL的完整示例:

    const url = new URL('https://example.com/api/search');
    url.searchParams.append('query', 'test');
    url.searchParams.append('tag', 'tag1');
    url.searchParams.append('tag', 'tag2');

    // https://example.com/api/search?query=test&tag=tag1&tag=tag2
    console.log(url.toString());

进入全屏 退出全屏

检查有效网址

你可以尝试使用正则表达式来验证URL,但要创建一个能完全匹配有效URL的正则表达式则非常困难。

相反,你可以使用 URL 接口。如果 URL 构造函数接收到无效的 URL,它会抛出错误。你可以用这个来验证 URL 是否有效:

    function 验证URL有效性(url) {
      try {
        new URL(url);
        return true;
      } catch (error) {
        return false;
      }
    }

切换到全屏模式, 退出全屏

使用新版本的浏览器,这变得更加简单。有一个新的 URL.canParse 静态方法,可以仅用一行代码完成类似验证。就像前面提到的 isValidURL 函数一样,它会检查一个可能的 URL 字符串并返回 truefalse,依据该 URL 字符串是否有效。

创建相对链接:

URL API 有一个强大的机制用于解析和转换相对 URL。通常,URL 构造函数的参数如果不是一个完整的有效 URL,会抛出错误。然而,你可以指定一个第二个参数作为基准,从这个基准来构建相对 URL。使用这种方法时,第一个参数可以不是有效的 URL,但第二个参数必须是有效的 URL。

我们先来看一个简单的例子吧。

    new URL('/about', 'https://example.com').href;

这是一个获取关于页面URL的JavaScript代码片段。

全屏模式 / 退出全屏

The URL 构建器使用基础 URL https://example.com,然后加上相对路径 /about,最终形成 https://example.com/about

这个怎么样,

new URL('profile', 'https://example.com/users').href; // 获取用户 'https://example.com/users' 的个人资料 URL 的 href 属性。

全屏模式 退出全屏

你可能以为这个链接应该是 https://example.com/users/profile,但实际上它是 https://example.com/profile。这种链接方式就像一个相对链接;它使用父路径部分,就是 example.com 的根路径,然后加上 profile

让我们再看一个使用相对URL的例子。你可以使用 .. 来返回上一级路径。

创建一个新URL,指向'https://example.com/users/123/profile'

进入全屏模式,退出全屏模式

这个链接是 https://example.com/profile。请记住,相对URL是从当前路径的父路径开始的。这个URL中的 .. 表示向上移动一个路径段。

如果你用相对网址调用 URL 构造器,并且指定的基网址无效或不完整,会出现错误。同样,如果你没有提供完整的基网址就使用相对网址,也会出现错误。

    new URL('../profile', '/about'); // 错误:相对路径不正确!
    new URL('../profile'); // 错误:相对路径不正确!

进入全屏 退出全屏

使用 window.location 对象:

你可能对 window.location 不陌生,它代表当前页面的 URL。这个对象还有一些属性,例如 hrefpathname,因此你可能误以为它就是一个 URL 对象。但实际上它是一个不同的对象,也就是 Location,它与 URL 对象有一些相似之处,但缺少一些属性,比如 searchParams

即使它不是URL对象,你仍然可以使用window.location来创建新的URL对象实例。你可以将window.location传递给URL构造函数,基于当前URL创建一个完整的URL,包括searchParams等,或者你甚至可以将其作为基础URL来构建相对路径的URL。

    new URL('/profile', window.location).href;

切换到全屏模式 退出全屏模式

URLPattern 匹配 URL 中的模式

使用 URL 可以轻松地获取路径。例如,在 URL https://example.com/api/users/123/profile 中,路径名是 /api/users/123/profile 这部分。如果我们只想从这个 URL 获取用户 ID 123 呢?

正如我们之前讨论过的,要创建合适的正则表达式来验证和提取网址的部分内容确实会有难度。

目前不是所有的浏览器都支持这项功能,但你可以使用 URLPattern API 来匹配并提取你指定模式下的 URL 部分。这对于单页面应用(SPA,即单页应用)中的客户端路由特别有用。

以用户个人资料页面的URL为例,让我们创建一个“URLPattern”来获取用户ID。我们可以用:开头表示一个带名字的占位符,之后就可以用来匹配URL中的这个部分:

    const pattern = new URLPattern('https://example.com/api/users/:userId/profile');
    const 匹配器 = pattern.exec('https://example.com/api/users/123/profile');
    console.log(匹配器.pathname.groups.userId); // 123

切换到全屏模式,退出全屏

当你在一个 URLPattern 上调用 exec 时,需要提供一个有效的 URL。它会返回一个匹配对象,该对象包含了 URL 各部分的属性(比如 protocolhostpathname 等等)。每个属性都有一个 groups 属性,该属性将占位符名称(如 :userId)映射到 URL 中的具体值。

如果你只关心 URL 的某一部分,比如路径名,你也可以在 URL 模式里使用通配符。或者,你可以传入一个包含你感兴趣的部分的 URL 对象。

    new URLPattern('https://*/api/users/:userId/profile');
    new URLPattern({ pathname: '/api/users/:userId/profile' });

全屏模式 退出全屏

URLPattern API 目前并非所有浏览器都支持。截至目前,Firefox 和 Safari 目前不支持此 API。请访问 CanIUse.com 获取最新信息。

摘要

URL API 是一个在 JavaScript 中用于构建、验证和操作 URL 的多功能接口工具。相比手动解析或使用正则表达式,它更安全且不易出错。通过使用 URLSearchParams 对象,你可以构建查询参数而无需担心字符串拼接或手动编码特殊字符的问题。

URLPattern API 将此更进一步,支持通配符和命名占位符,因此你可以根据需要解析和分割 URL 以满足你应用的需求!更多资料:

省略内容

只需几分钟就能快速设置好 LogRocket 的现代化错误追踪。

  1. 访问 https://logrocket.com/signup/ 获取应用 ID。
  2. 使用 NPM 或 script 标签安装 LogRocket。LogRocket.init() 需要在客户端调用,而不是在服务器端。

NPM:

// 安装依赖:
$ npm i --save logrocket 

// 代码示例:

// 导入 LogRocket:
import LogRocket from 'logrocket'; 
// 初始化 LogRocket:
LogRocket.init('app/id');

进入全屏 退出全屏

脚本标签:

在您的HTML中,请添加以下代码段:

    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>

全屏模式 退出全屏

3.(可选地) 安装插件以进行更深入的集成,与您的技术组合:

  • Redux 中间件
  • ngrx 中间件
  • Vuex 插件

现在就开始

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消