如何在JavaScript中构建URL

通常情况下,我们需要在JavaScript中创建URL,以请求资源或重定向用户。这似乎是一个简单的任务,但URL可能非常微妙和复杂,需要非常注意才能正确处理。如果您曾经使用过不同的编码和多个查询参数,那么这一点尤为明显。

很多开发者会直接使用模板字符串来构建URL。毕竟,URL只是字符串,可以使用插值来添加所需的参数。然而,这种方法容易出错,可能导致错误。让我们来看一个例子:

const query = "Where's Waldø?";
const locale = "en-US";
const campaign = "promo_email";

const url = `https://examp.le?q=${query}&lang=${locale}&from=${campaign}`;
// "https://examp.le?q=Where's Waldø?&lang=en-US&from=promo_email"

如您所见,模板字符串不适合用于URL,因为它们不会编码特殊字符。如果您使用JavaScript已经有一段时间,您可能会使用encodeURIComponent()来解决这个问题:

const query = "Where's Waldø?";
const locale = "en-US";
const campaign = "promo_email";

const url = `https://examp.le
  ?q=${
    encodeURIComponent(query)
  }&lang=${
    encodeURIComponent(locale)
  }&from=${
    encodeURIComponent(campaign)
  }`;
// "https://examp.le\n  ?q=Where's%20Wald%C3%B8%3F&lang=en-US&from=promo_email"

当然,这解决了编码的问题,但多行字符串在URL中插入了一个换行符(\n)。这是因为模板字符串保留了空格,导致出现此类问题。将字符串拆分为多行并进行连接可以解决这个问题,但代码变得越来越丑陋。

显然,可能会出现其他问题,使得这成为一个非平凡的问题。幸运的是,在JavaScript中有一种更好的方式来构建URL,即使用URL对象。让我们看看如何使用它来解决上面的问题:

const query = "Where's Waldø?";
const locale = "zh-CN";
const campaign = "promo_email";

// 好的
const url = new URL('https://examp.le');

url.searchParams.set('q', query);
url.searchParams.set('lang', locale);
url.searchParams.set('from', campaign);

url.toString();
// 'https://examp.le/?q=Where%27s+Wald%C3%B8%3F&lang=zh-CN&from=promo_email'

诚然,使用URL对象可能会更冗长一些,但这是一个值得的权衡。代码更易读、易维护,而且更不容易出错。查询参数现在被正确编码,并且自动添加了分隔符。

虽然查询参数是处理URL时最常见的问题,但URL对象在许多其他情况下也很有用。例如,您可以更改URL的协议、主机名、端口、路径、哈希等等,甚至可以解析现有URL为其组件。如果您感兴趣,可以查看之前的文章,了解如何编辑URL参数window.location速查表