目录

🧉 JavaScript URL 对象

是 JavaScript 内建的 用于创建和解析 URL 的便捷接口。

没有任何一个网络方法一定需要使用 URL 对象,字符串就足够了。使用 URL 对象可以对付一些特殊的情况。

# 创建 URL 对象

new URL(url [, base])
1
  • url :完整的 URL 地址,或者设置了 base 可以只写路径。

  • base : 可选的 base URL:如果设置了此参数,且参数 url 只有路径,则会根据这个 base 生成 URL。

🌰 例子:

let url = new URL('https://www.bilibili.com/');
1
let url = new URL('https://www.bilibili.com/login');
// 或者
let url = new URL('/login', 'https://www.bilibili.com/');
1
2
3

两种方式相同。

🌰 例子 / 根据先用的 URL 对象创建新的 URL :

let url = new URL('https://javascript.info/profile/admin');
let newUrl = new URL('tester', url);

alert(newUrl); // https://javascript.info/profile/tester
1
2
3
4

# URL 对象的组件属性

  • href :完整的 URL,与 url.toString() 相同;
  • protocol :网络协议。以冒号字符 : 结尾;
  • search :以问号 ? 开头的一串参数;
  • hash :以哈希字符 # 开头的数据。
  • 如果存在 HTTP 身份验证,则这里可能还会有 userpassword 属性: http://login:password@site.com (较少用)

🌰 例子:

let url = new URL('https://javascript.info/url');

alert(url.protocol); // https:
alert(url.host);     // javascript.info
alert(url.pathname); // /url
1
2
3
4
5

image-20220601151635830

可以将 URL 对象传递给其他方法(网络和大多数),而不是仅使用 URL 字符串。例如,在 fetchXMLHttpRequest 中使用 URL 对象,几乎可以在任何需要 URL 字符串的地方都能使用 URL 对象。

通常, URL 对象可以替代字符串传递给任何方法,因为大多数方法都会执行字符串转换,这会将 URL 对象转换为具有完整 URL 的字符串。

# URL 对象中的参数

如果想要创建一个具有参数的 URL,例如: https://google.com/search?query=JavaScript 。可以在 URL 字符串中提供它们:

new URL('https://google.com/search?query=JavaScript')
1

当参数中包含空格,非拉丁字母等,参数就需要被编码。

更多复杂的参数可以使用 URL 的属性 url.searchParams ,是 URL SearchParams 类型的对象。为搜索参数提供了简便的方法。

  • append(name, value) :按照 namevalue 添加参数;
  • delete(name) :按照 name 移除参数;
  • get(name) :按照 name 获取参数;
  • getAll(name) :获取相同 name 的所有参数;
  • has(name) :按照 name 检查参数是否存在;
  • set(name, value) :set/replace 参数,
  • sort() :按 name 对参数进行排序,很少使用;
  • …… 并且它是可迭代的,类似于 Map

🌰 例子:

let url = new URL('https://google.com/search');

url.searchParams.set('q', 'test me!'); // 添加带有一个空格和一个 ! 的参数
alert(url); // https://google.com/search?q=test+me%21

url.searchParams.set('tbs', 'qdr:y'); // 添加带有一个冒号 : 的参数

// 参数会被自动编码
alert(url); // https://google.com/search?q=test+me%21&tbs=qdr%3Ay

// 遍历搜索参数(被解码)
for(let [name, value] of url.searchParams) {
  alert(`${name}=${value}`); // q=test me!,然后是 tbs=qdr:y
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

URL 的编码。

标准定义了 URL 中允许哪些字符,不允许哪些字符。

那些不被允许的字符必须被编码,例如非拉丁字母和空格 —— 用其 UTF-8 代码代替,前缀为 % ,例如 %20 (由于历史原因,空格可以用 + 编码,但这是一个例外)。

使用 URL 对象可以自动处理这些非规范的参数。

🌰 例子:

let url = new URL('https://ru.wikipedia.org/wiki/Тест');

url.searchParams.set('key', 'ъ');
alert(url); //https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%81%D1%82?key=%D1%8A
1
2
3
4

# 编码 URL 字符串

在 URL 对象之前,使用 URL 字符串。可以通过一些内建函数 解码 / 编码 URL:

  • encodeURI :编码整个 URL;
  • decodeURI : 解码为编码前的状态;
  • encodeURIComponent :编码 URL 组件,例如搜索参数,或者 hash,或者 pathname;
  • decodeURIComponent :解码为编码前的状态;

encodeURI / encodeURIComponent 区别:

  • 对于一个 URL 整体,可以使用 encodeURI ;对于 URL 参数,应该用 encodeURIComponent

  • encodeURI 仅编码 URL 中完全禁止的字符。

  • encodeURIComponent 也编码这类字符,此外,还编码 #$&+,/:;=?@ 字符。

🌰 例子:

// 在 url 路径中使用西里尔字符
let url = encodeURI('http://site.com/привет');

alert(url); // http://site.com/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82
1
2
3
4
let music = encodeURIComponent('Rock&Roll');

let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock%26Roll
1
2
3
4

如果使用 encodeURI

let music = encodeURI('Rock&Roll');

let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock&Roll
1
2
3
4

encodeURI 没有对 & 进行编码,因为它对于整个 URL 来说是合法的字符。但是不应该拆分这个参数。

所以对于每个搜索参数,应该使用 encodeURIComponent ,以将其正确地插入到 URL 字符串中。最安全的方式是对 name 和 value 都进行编码,除非能够绝对确保它只包含允许的字符。

📢 上次更新: 2022/09/02, 10:18:16