URL#

稳定性:2 - 稳定

源代码: lib/url.js

node:url 模块提供了用于 URL 解析和分析的实用工具。 可以使用以下方式访问它

import url from 'node:url';const url = require('node:url');

URL 字符串和 URL 对象#

URL 字符串是包含多个有意义组件的结构化字符串。 解析后,将返回一个 URL 对象,其中包含每个组件的属性。

node:url 模块提供了两个用于处理 URL 的 API:一个是特定于 Node.js 的旧版 API,另一个是实现与 Web 浏览器使用的相同的 WHATWG URL 标准 的较新 API。

下面提供了 WHATWG 和旧版 API 之间的比较。 在 URL 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash' 上方,显示了旧版 url.parse() 返回的对象属性。 下方是 WHATWG URL 对象的属性。

WHATWG URL 的 origin 属性包括 protocolhost,但不包括 usernamepassword

┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                              href                                              │
├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤
│ protocol │  │        auth         │          host          │           path            │ hash  │
│          │  │                     ├─────────────────┬──────┼──────────┬────────────────┤       │
│          │  │                     │    hostname     │ port │ pathname │     search     │       │
│          │  │                     │                 │      │          ├─┬──────────────┤       │
│          │  │                     │                 │      │          │ │    query     │       │
"  https:   //    user   :   pass   @ sub.example.com : 8080   /p/a/t/h  ?  query=string   #hash "
│          │  │          │          │    hostname     │ port │          │                │       │
│          │  │          │          ├─────────────────┴──────┤          │                │       │
│ protocol │  │ username │ password │          host          │          │                │       │
├──────────┴──┼──────────┴──────────┼────────────────────────┤          │                │       │
│   origin    │                     │         origin         │ pathname │     search     │ hash  │
├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤
│                                              href                                              │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(All spaces in the "" line should be ignored. They are purely for formatting.) 

使用 WHATWG API 解析 URL 字符串

const myURL =
  new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'); 

使用旧版 API 解析 URL 字符串

import url from 'node:url';
const myURL =
  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');const url = require('node:url');
const myURL =
  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');

从组件部分构造 URL 并获取构造的字符串#

可以使用属性设置器或模板字面量字符串从组件部分构造 WHATWG URL

const myURL = new URL('https://example.org');
myURL.pathname = '/a/b/c';
myURL.search = '?d=e';
myURL.hash = '#fgh'; 
const pathname = '/a/b/c';
const search = '?d=e';
const hash = '#fgh';
const myURL = new URL(`https://example.org${pathname}${search}${hash}`); 

要获取构造的 URL 字符串,请使用 href 属性访问器

console.log(myURL.href); 

WHATWG URL API#

类:URL#

浏览器兼容的 URL 类,通过遵循 WHATWG URL 标准实现。 已解析 URL 的示例 可以在标准本身中找到。 URL 类也可在全局对象上使用。

按照浏览器约定,URL 对象的所有属性都作为类原型上的 getter 和 setter 实现,而不是作为对象本身的数据属性。 因此,与 旧版 urlObject 不同,在 URL 对象的任何属性上使用 delete 关键字(例如 delete myURL.protocoldelete myURL.pathname 等)没有任何效果,但仍然会返回 true

new URL(input[, base])#
  • input <string> 要解析的绝对或相对输入 URL。 如果 input 是相对的,则需要 base。 如果 input 是绝对的,则会忽略 base。 如果 input 不是字符串,则首先将其 转换为字符串
  • base <string> 如果 input 不是绝对的,则要解析的基础 URL。 如果 base 不是字符串,则首先将其 转换为字符串

通过相对于 base 解析 input 来创建新的 URL 对象。 如果 base 作为字符串传递,则将等效于 new URL(base) 进行解析。

const myURL = new URL('/foo', 'https://example.org/');
// https://example.org/foo 

URL 构造函数可作为全局对象上的属性访问。 也可以从内置 url 模块导入

import { URL } from 'node:url';
console.log(URL === globalThis.URL); // Prints 'true'.console.log(URL === require('node:url').URL); // Prints 'true'.

如果 inputbase 不是有效的 URL,则会引发 TypeError。 请注意,将努力将给定的值强制转换为字符串。 例如

const myURL = new URL({ toString: () => 'https://example.org/' });
// https://example.org/ 

出现在 input 主机名中的 Unicode 字符将使用 Punycode 算法自动转换为 ASCII。

const myURL = new URL('https://測試');
// https://xn--g6w251d/ 

如果事先不知道 input 是否为绝对 URL 并且提供了 base,建议验证 URL 对象的 origin 是否符合预期。

let myURL = new URL('http://Example.com/', 'https://example.org/');
// http://example.com/

myURL = new URL('https://Example.com/', 'https://example.org/');
// https://example.com/

myURL = new URL('foo://Example.com/', 'https://example.org/');
// foo://Example.com/

myURL = new URL('http:Example.com/', 'https://example.org/');
// http://example.com/

myURL = new URL('https:Example.com/', 'https://example.org/');
// https://example.org/Example.com/

myURL = new URL('foo:Example.com/', 'https://example.org/');
// foo:Example.com/ 
url.hash#

获取和设置 URL 的片段部分。

const myURL = new URL('https://example.org/foo#bar');
console.log(myURL.hash);
// Prints #bar

myURL.hash = 'baz';
console.log(myURL.href);
// Prints https://example.org/foo#baz 

hash 属性中包含的无效 URL 字符将进行 百分比编码。 要进行百分比编码的字符的选择可能与 url.parse()url.format() 方法产生的字符略有不同。

url.host#

获取和设置 URL 的主机部分。

const myURL = new URL('https://example.org:81/foo');
console.log(myURL.host);
// Prints example.org:81

myURL.host = 'example.com:82';
console.log(myURL.href);
// Prints https://example.com:82/foo 

分配给 host 属性的无效主机值将被忽略。

url.hostname#

获取和设置 URL 的主机名部分。 url.hosturl.hostname 之间的主要区别在于 url.hostname包含端口。

const myURL = new URL('https://example.org:81/foo');
console.log(myURL.hostname);
// Prints example.org

// Setting the hostname does not change the port
myURL.hostname = 'example.com';
console.log(myURL.href);
// Prints https://example.com:81/foo

// Use myURL.host to change the hostname and port
myURL.host = 'example.org:82';
console.log(myURL.href);
// Prints https://example.org:82/foo 

分配给 hostname 属性的无效主机名值将被忽略。

url.href#

获取和设置序列化的 URL。

const myURL = new URL('https://example.org/foo');
console.log(myURL.href);
// Prints https://example.org/foo

myURL.href = 'https://example.com/bar';
console.log(myURL.href);
// Prints https://example.com/bar 

获取 href 属性的值等效于调用 url.toString()

将此属性的值设置为新值等效于使用 new URL(value) 创建新的 URL 对象。 将修改每个 URL 对象的属性。

如果分配给 href 属性的值不是有效的 URL,则会引发 TypeError

url.origin#

获取 URL 来源的只读序列化。

const myURL = new URL('https://example.org/foo/bar?baz');
console.log(myURL.origin);
// Prints https://example.org 
const idnURL = new URL('https://測試');
console.log(idnURL.origin);
// Prints https://xn--g6w251d

console.log(idnURL.hostname);
// Prints xn--g6w251d 
url.password#

获取和设置 URL 的密码部分。

const myURL = new URL('https://abc:xyz@example.com');
console.log(myURL.password);
// Prints xyz

myURL.password = '123';
console.log(myURL.href);
// Prints https://abc:123@example.com/ 

分配给 password 属性的值中包含的无效 URL 字符会进行 百分比编码。 要进行百分比编码的字符的选择可能与 url.parse()url.format() 方法生成的结果略有不同。

url.pathname#

获取和设置 URL 的路径部分。

const myURL = new URL('https://example.org/abc/xyz?123');
console.log(myURL.pathname);
// Prints /abc/xyz

myURL.pathname = '/abcdef';
console.log(myURL.href);
// Prints https://example.org/abcdef?123 

分配给 pathname 属性的值中包含的无效 URL 字符会进行 百分比编码。 要进行百分比编码的字符的选择可能与 url.parse()url.format() 方法生成的结果略有不同。

url.port#

获取和设置 URL 的端口部分。

端口值可以是 065535(包括)范围内的数字或包含数字的字符串。 将值设置为给定 protocolURL 对象的默认端口将导致 port 值变为空字符串 ('')。

端口值可以是一个空字符串,在这种情况下,端口取决于协议/方案

协议端口
"ftp"21
"file"
"http"80
"https"443
"ws"80
"wss"443

在给端口赋值后,该值将首先使用 .toString() 转换为字符串。

如果该字符串无效但它以数字开头,则将前导数字分配给 port。 如果该数字位于上述范围之外,则会被忽略。

const myURL = new URL('https://example.org:8888');
console.log(myURL.port);
// Prints 8888

// Default ports are automatically transformed to the empty string
// (HTTPS protocol's default port is 443)
myURL.port = '443';
console.log(myURL.port);
// Prints the empty string
console.log(myURL.href);
// Prints https://example.org/

myURL.port = 1234;
console.log(myURL.port);
// Prints 1234
console.log(myURL.href);
// Prints https://example.org:1234/

// Completely invalid port strings are ignored
myURL.port = 'abcd';
console.log(myURL.port);
// Prints 1234

// Leading numbers are treated as a port number
myURL.port = '5678abcd';
console.log(myURL.port);
// Prints 5678

// Non-integers are truncated
myURL.port = 1234.5678;
console.log(myURL.port);
// Prints 1234

// Out-of-range numbers which are not represented in scientific notation
// will be ignored.
myURL.port = 1e10; // 10000000000, will be range-checked as described below
console.log(myURL.port);
// Prints 1234 

包含小数点的数字,例如浮点数或科学计数法中的数字,不例外于此规则。 假设它们有效,则小数点之前的前导数字将设置为 URL 的端口

myURL.port = 4.567e21;
console.log(myURL.port);
// Prints 4 (because it is the leading number in the string '4.567e21') 
url.protocol#

获取和设置 URL 的协议部分。

const myURL = new URL('https://example.org');
console.log(myURL.protocol);
// Prints https:

myURL.protocol = 'ftp';
console.log(myURL.href);
// Prints ftp://example.org/ 

分配给 protocol 属性的无效 URL 协议值会被忽略。

特殊方案#

WHATWG URL 标准认为少数 URL 协议方案在解析和序列化方面是*特殊的*。 当使用这些特殊协议之一解析 URL 时,url.protocol 属性可能会更改为另一个特殊协议,但不能更改为非特殊协议,反之亦然。

例如,从 http 更改为 https 有效

const u = new URL('http://example.org');
u.protocol = 'https';
console.log(u.href);
// https://example.org/ 

但是,从 http 更改为假设的 fish 协议无效,因为新协议不特殊。

const u = new URL('http://example.org');
u.protocol = 'fish';
console.log(u.href);
// http://example.org/ 

同样,也不允许从非特殊协议更改为特殊协议

const u = new URL('fish://example.org');
u.protocol = 'http';
console.log(u.href);
// fish://example.org 

根据 WHATWG URL 标准,特殊协议方案是 ftpfilehttphttpswswss

url.search#

获取和设置 URL 的序列化查询部分。

const myURL = new URL('https://example.org/abc?123');
console.log(myURL.search);
// Prints ?123

myURL.search = 'abc=xyz';
console.log(myURL.href);
// Prints https://example.org/abc?abc=xyz 

出现在分配给 search 属性的值中的任何无效 URL 字符都将进行 百分比编码。 要进行百分比编码的字符的选择可能与 url.parse()url.format() 方法生成的结果略有不同。

url.searchParams#

获取代表 URL 查询参数的 URLSearchParams 对象。 此属性是只读的,但它提供的 URLSearchParams 对象可用于改变 URL 实例; 要替换 URL 的整个查询参数,请使用 url.search setter。 有关详细信息,请参见 URLSearchParams 文档。

使用 .searchParams 修改 URL 时要小心,因为根据 WHATWG 规范,URLSearchParams 对象使用不同的规则来确定要百分比编码的字符。 例如,URL 对象不会百分比编码 ASCII 波浪号 (~) 字符,而 URLSearchParams 将始终对其进行编码

const myURL = new URL('https://example.org/abc?foo=~bar');

console.log(myURL.search);  // prints ?foo=~bar

// Modify the URL via searchParams...
myURL.searchParams.sort();

console.log(myURL.search);  // prints ?foo=%7Ebar 
url.username#

获取和设置 URL 的用户名部分。

const myURL = new URL('https://abc:xyz@example.com');
console.log(myURL.username);
// Prints abc

myURL.username = '123';
console.log(myURL.href);
// Prints https://123:xyz@example.com/ 

出现在分配给 username 属性的值中的任何无效 URL 字符都将进行 百分比编码。 要进行百分比编码的字符的选择可能与 url.parse()url.format() 方法生成的结果略有不同。

url.toString()#

URL 对象上的 toString() 方法返回序列化的 URL。 返回的值等效于 url.hrefurl.toJSON() 的值。

url.toJSON()#

URL 对象上的 toJSON() 方法返回序列化的 URL。 返回的值等效于 url.hrefurl.toString() 的值。

当使用 JSON.stringify() 序列化 URL 对象时,会自动调用此方法。

const myURLs = [
  new URL('https://www.example.com'),
  new URL('https://test.example.org'),
];
console.log(JSON.stringify(myURLs));
// Prints ["https://www.example.com/","https://test.example.org/"] 
URL.createObjectURL(blob)#

创建表示给定 <Blob> 对象的 'blob:nodedata:...' URL 字符串,该字符串可用于稍后检索 Blob

const {
  Blob,
  resolveObjectURL,
} = require('node:buffer');

const blob = new Blob(['hello']);
const id = URL.createObjectURL(blob);

// later...

const otherBlob = resolveObjectURL(id);
console.log(otherBlob.size); 

由已注册的 <Blob> 存储的数据将保留在内存中,直到调用 URL.revokeObjectURL() 将其删除。

Blob 对象在当前线程中注册。 如果使用 Worker 线程,则在一个 Worker 中注册的 Blob 对象将无法用于其他 worker 或主线程。

URL.revokeObjectURL(id)#
  • id <string> 先前调用 URL.createObjectURL() 返回的 'blob:nodedata:... URL 字符串。

删除由给定 ID 标识的已存储 <Blob>。 尝试撤销未注册的 ID 将静默失败。

URL.canParse(input[, base])#
  • input <string> 要解析的绝对或相对输入 URL。 如果 input 是相对的,则需要 base。 如果 input 是绝对的,则会忽略 base。 如果 input 不是字符串,则首先将其 转换为字符串
  • base <string> 如果 input 不是绝对的,则要解析的基础 URL。 如果 base 不是字符串,则首先将其 转换为字符串
  • 返回: <boolean>

检查相对于 baseinput 是否可以解析为 URL

const isValid = URL.canParse('/foo', 'https://example.org/'); // true

const isNotValid = URL.canParse('/foo'); // false 
URL.parse(input[, base])#
  • input <string> 要解析的绝对或相对输入 URL。 如果 input 是相对的,则需要 base。 如果 input 是绝对的,则会忽略 base。 如果 input 不是字符串,则首先将其 转换为字符串
  • base <string> 如果 input 不是绝对的,则要解析的基础 URL。 如果 base 不是字符串,则首先将其 转换为字符串
  • 返回: <URL> | <null>

将字符串解析为 URL。 如果提供了 base,则它将用作解析非绝对 input URL 的基本 URL。 如果 input 无效,则返回 null

类: URLPattern#

稳定性: 1 - 实验性的

URLPattern API 提供了一个接口,用于将 URL 或 URL 的部分与模式进行匹配。

const myPattern = new URLPattern('https://node.org.cn/docs/latest/api/*.html');
console.log(myPattern.exec('https://node.org.cn/docs/latest/api/dns.html'));
// Prints:
// {
//  "hash": { "groups": {  "0": "" },  "input": "" },
//  "hostname": { "groups": {}, "input": "nodejs.org" },
//  "inputs": [
//    "https://node.org.cn/docs/latest/api/dns.html"
//  ],
//  "password": { "groups": { "0": "" }, "input": "" },
//  "pathname": { "groups": { "0": "dns" }, "input": "/docs/latest/api/dns.html" },
//  "port": { "groups": {}, "input": "" },
//  "protocol": { "groups": {}, "input": "https" },
//  "search": { "groups": { "0": "" }, "input": "" },
//  "username": { "groups": { "0": "" }, "input": "" }
// }

console.log(myPattern.test('https://node.org.cn/docs/latest/api/dns.html'));
// Prints: true 
new URLPattern()#

实例化一个新的空 URLPattern 对象。

new URLPattern(string[, baseURL][, options])#

string 解析为 URL,并使用它来实例化新的 URLPattern 对象。

如果未指定 baseURL,则默认为 undefined

选项可以具有 ignoreCase 布尔属性,如果设置为 true,则启用不区分大小写的匹配。

构造函数可以抛出 TypeError 来指示解析失败。

new URLPattern(obj[, baseURL][, options])#

Object 解析为输入模式,并使用它来实例化新的 URLPattern 对象。 对象成员可以是 protocolusernamepasswordhostnameportpathnamesearchhashbaseURL 中的任何一个。

如果未指定 baseURL,则默认为 undefined

选项可以具有 ignoreCase 布尔属性,如果设置为 true,则启用不区分大小写的匹配。

构造函数可以抛出 TypeError 来指示解析失败。

urlPattern.exec(input[, baseURL])#

输入可以是字符串或提供各个 URL 部分的对象。对象成员可以是 protocolusernamepasswordhostnameportpathnamesearchhashbaseURL 中的任何一个。

如果未指定 baseURL,则默认为 undefined

返回一个对象,该对象具有一个 inputs 键,其中包含传递给函数的参数数组,以及包含匹配的输入和匹配的组的 URL 组件的键。

const myPattern = new URLPattern('https://node.org.cn/docs/latest/api/*.html');
console.log(myPattern.exec('https://node.org.cn/docs/latest/api/dns.html'));
// Prints:
// {
//  "hash": { "groups": {  "0": "" },  "input": "" },
//  "hostname": { "groups": {}, "input": "nodejs.org" },
//  "inputs": [
//    "https://node.org.cn/docs/latest/api/dns.html"
//  ],
//  "password": { "groups": { "0": "" }, "input": "" },
//  "pathname": { "groups": { "0": "dns" }, "input": "/docs/latest/api/dns.html" },
//  "port": { "groups": {}, "input": "" },
//  "protocol": { "groups": {}, "input": "https" },
//  "search": { "groups": { "0": "" }, "input": "" },
//  "username": { "groups": { "0": "" }, "input": "" }
// } 
urlPattern.test(input[, baseURL])#

输入可以是字符串或提供各个 URL 部分的对象。对象成员可以是 protocolusernamepasswordhostnameportpathnamesearchhashbaseURL 中的任何一个。

如果未指定 baseURL,则默认为 undefined

返回一个布尔值,指示输入是否与当前模式匹配。

const myPattern = new URLPattern('https://node.org.cn/docs/latest/api/*.html');
console.log(myPattern.test('https://node.org.cn/docs/latest/api/dns.html'));
// Prints: true 

类:URLSearchParams#

URLSearchParams API 提供对 URL 的查询的读取和写入访问。 URLSearchParams 类也可以与以下四个构造函数之一单独使用。 URLSearchParams 类也可在全局对象上使用。

WHATWG URLSearchParams 接口和 querystring 模块具有相似的目的,但 querystring 模块的用途更通用,因为它允许自定义分隔符字符(&=)。 另一方面,此 API 专为 URL 查询字符串而设计。

const myURL = new URL('https://example.org/?abc=123');
console.log(myURL.searchParams.get('abc'));
// Prints 123

myURL.searchParams.append('abc', 'xyz');
console.log(myURL.href);
// Prints https://example.org/?abc=123&abc=xyz

myURL.searchParams.delete('abc');
myURL.searchParams.set('a', 'b');
console.log(myURL.href);
// Prints https://example.org/?a=b

const newSearchParams = new URLSearchParams(myURL.searchParams);
// The above is equivalent to
// const newSearchParams = new URLSearchParams(myURL.search);

newSearchParams.append('a', 'c');
console.log(myURL.href);
// Prints https://example.org/?a=b
console.log(newSearchParams.toString());
// Prints a=b&a=c

// newSearchParams.toString() is implicitly called
myURL.search = newSearchParams;
console.log(myURL.href);
// Prints https://example.org/?a=b&a=c
newSearchParams.delete('a');
console.log(myURL.href);
// Prints https://example.org/?a=b&a=c 
new URLSearchParams()#

实例化一个新的空 URLSearchParams 对象。

new URLSearchParams(string)#

string 解析为查询字符串,并使用它来实例化新的 URLSearchParams 对象。 如果存在,则忽略前导 '?'

let params;

params = new URLSearchParams('user=abc&query=xyz');
console.log(params.get('user'));
// Prints 'abc'
console.log(params.toString());
// Prints 'user=abc&query=xyz'

params = new URLSearchParams('?user=abc&query=xyz');
console.log(params.toString());
// Prints 'user=abc&query=xyz' 
new URLSearchParams(obj)#
  • obj <Object> 表示键值对集合的对象

使用查询哈希映射实例化新的 URLSearchParams 对象。 obj 的每个属性的键和值始终强制转换为字符串。

querystring 模块不同,不允许使用数组值形式的重复键。 数组使用 array.toString() 进行字符串化,该方法只是用逗号连接所有数组元素。

const params = new URLSearchParams({
  user: 'abc',
  query: ['first', 'second'],
});
console.log(params.getAll('query'));
// Prints [ 'first,second' ]
console.log(params.toString());
// Prints 'user=abc&query=first%2Csecond' 
new URLSearchParams(iterable)#
  • iterable <Iterable> 元素是键值对的可迭代对象

以类似于 <Map> 的构造函数的方式,使用可迭代映射实例化新的 URLSearchParams 对象。 iterable 可以是 Array 或任何可迭代对象。 这意味着 iterable 可以是另一个 URLSearchParams,在这种情况下,构造函数将只创建所提供的 URLSearchParams 的克隆。 iterable 的元素是键值对,它们本身可以是任何可迭代对象。

允许重复的键。

let params;

// Using an array
params = new URLSearchParams([
  ['user', 'abc'],
  ['query', 'first'],
  ['query', 'second'],
]);
console.log(params.toString());
// Prints 'user=abc&query=first&query=second'

// Using a Map object
const map = new Map();
map.set('user', 'abc');
map.set('query', 'xyz');
params = new URLSearchParams(map);
console.log(params.toString());
// Prints 'user=abc&query=xyz'

// Using a generator function
function* getQueryPairs() {
  yield ['user', 'abc'];
  yield ['query', 'first'];
  yield ['query', 'second'];
}
params = new URLSearchParams(getQueryPairs());
console.log(params.toString());
// Prints 'user=abc&query=first&query=second'

// Each key-value pair must have exactly two elements
new URLSearchParams([
  ['user', 'abc', 'error'],
]);
// Throws TypeError [ERR_INVALID_TUPLE]:
//        Each query pair must be an iterable [name, value] tuple 
urlSearchParams.append(name, value)#

将新的名称-值对追加到查询字符串。

urlSearchParams.delete(name[, value])#

如果提供了 value,则删除所有 name 为 name 且 value 为 value 的名称-值对。

如果未提供 value,则删除所有名称为 name 的名称-值对。

urlSearchParams.entries()#

返回查询中每个名称-值对的 ES6 Iterator。 迭代器的每个项目都是一个 JavaScript ArrayArray 的第一个项目是 nameArray 的第二个项目是 value

别名为 urlSearchParams[@@iterator]()

urlSearchParams.forEach(fn[, thisArg])#
  • fn <Function> 为查询中的每个名称-值对调用
  • thisArg <Object> 用作调用 fn 时的 this

迭代查询中的每个名称-值对,并调用给定的函数。

const myURL = new URL('https://example.org/?a=b&c=d');
myURL.searchParams.forEach((value, name, searchParams) => {
  console.log(name, value, myURL.searchParams === searchParams);
});
// Prints:
//   a b true
//   c d true 
urlSearchParams.get(name)#
  • name <string>
  • 返回:<string> | <null> 如果没有具有给定 name 的名称-值对,则返回字符串或 null

返回名称为 name 的第一个名称-值对的值。 如果没有这样的对,则返回 null

urlSearchParams.getAll(name)#

返回名称为 name 的所有名称-值对的值。 如果没有这样的对,则返回一个空数组。

urlSearchParams.has(name[, value])#

检查 URLSearchParams 对象是否包含基于 name 和可选 value 参数的键值对。

如果提供了 value,则当存在具有相同 namevalue 的名称-值对时,返回 true

如果未提供 value,则如果至少存在一个名称为 name 的名称-值对,则返回 true

urlSearchParams.keys()#

返回每个名称-值对的名称的 ES6 Iterator

const params = new URLSearchParams('foo=bar&foo=baz');
for (const name of params.keys()) {
  console.log(name);
}
// Prints:
//   foo
//   foo 
urlSearchParams.set(name, value)#

将与 name 关联的 URLSearchParams 对象中的值设置为 value。 如果存在任何名称为 name 的预先存在的名称-值对,则将第一个此类对的值设置为 value 并删除所有其他对。 如果没有,则将名称-值对追加到查询字符串。

const params = new URLSearchParams();
params.append('foo', 'bar');
params.append('foo', 'baz');
params.append('abc', 'def');
console.log(params.toString());
// Prints foo=bar&foo=baz&abc=def

params.set('foo', 'def');
params.set('xyz', 'opq');
console.log(params.toString());
// Prints foo=def&abc=def&xyz=opq 
urlSearchParams.size#

参数条目的总数。

urlSearchParams.sort()#

按名称就地对所有现有的名称-值对进行排序。 排序是使用稳定排序算法完成的,因此保留了具有相同名称的名称-值对之间的相对顺序。

特别是,此方法可用于增加缓存命中率。

const params = new URLSearchParams('query[]=abc&type=search&query[]=123');
params.sort();
console.log(params.toString());
// Prints query%5B%5D=abc&query%5B%5D=123&type=search 
urlSearchParams.toString()#

返回序列化为字符串的搜索参数,并在必要时对字符进行百分比编码。

urlSearchParams.values()#

返回每个名称-值对的值的 ES6 Iterator

urlSearchParams[Symbol.iterator]()#

返回查询字符串中每个名称-值对的 ES6 Iterator。 迭代器的每个项目都是一个 JavaScript ArrayArray 的第一个项目是 nameArray 的第二个项目是 value

别名为 urlSearchParams.entries()

const params = new URLSearchParams('foo=bar&xyz=baz');
for (const [name, value] of params) {
  console.log(name, value);
}
// Prints:
//   foo bar
//   xyz baz 

url.domainToASCII(domain)#

返回 domainPunycode ASCII 序列化。 如果 domain 是无效的域,则返回空字符串。

它执行与 url.domainToUnicode() 相反的操作。

import url from 'node:url';

console.log(url.domainToASCII('español.com'));
// Prints xn--espaol-zwa.com
console.log(url.domainToASCII('中文.com'));
// Prints xn--fiq228c.com
console.log(url.domainToASCII('xn--iñvalid.com'));
// Prints an empty stringconst url = require('node:url');

console.log(url.domainToASCII('español.com'));
// Prints xn--espaol-zwa.com
console.log(url.domainToASCII('中文.com'));
// Prints xn--fiq228c.com
console.log(url.domainToASCII('xn--iñvalid.com'));
// Prints an empty string

url.domainToUnicode(domain)#

返回 domain 的 Unicode 序列化。 如果 domain 是无效的域,则返回空字符串。

它执行与 url.domainToASCII() 相反的操作。

import url from 'node:url';

console.log(url.domainToUnicode('xn--espaol-zwa.com'));
// Prints español.com
console.log(url.domainToUnicode('xn--fiq228c.com'));
// Prints 中文.com
console.log(url.domainToUnicode('xn--iñvalid.com'));
// Prints an empty stringconst url = require('node:url');

console.log(url.domainToUnicode('xn--espaol-zwa.com'));
// Prints español.com
console.log(url.domainToUnicode('xn--fiq228c.com'));
// Prints 中文.com
console.log(url.domainToUnicode('xn--iñvalid.com'));
// Prints an empty string

url.fileURLToPath(url[, options])#

  • url <URL> | <string> 要转换为路径的文件 URL 字符串或 URL 对象。
  • options <Object>
    • windows <boolean> | <undefined> 如果 path 应该作为 Windows 文件路径返回,则为 true;如果应该作为 posix 文件路径返回,则为 false;如果应该使用系统默认值,则为 undefined默认值: undefined
  • 返回: <string> 完全解析的特定于平台的 Node.js 文件路径。

此函数确保对百分号编码字符进行正确的解码,并确保跨平台有效的绝对路径字符串。

import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);

new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
fileURLToPath('file:///C:/path/');         // Correct:   C:\path\ (Windows)

new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)

new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
fileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)

new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)const { fileURLToPath } = require('node:url');
new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
fileURLToPath('file:///C:/path/');         // Correct:   C:\path\ (Windows)

new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)

new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
fileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)

new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)

url.format(URL[, options])#

  • URL <URL> 一个 WHATWG URL 对象
  • options <Object>
    • auth <boolean> 如果序列化的 URL 字符串应包含用户名和密码,则为 true,否则为 false默认值: true
    • fragment <boolean> 如果序列化的 URL 字符串应包含片段,则为 true,否则为 false默认值: true
    • search <boolean> 如果序列化的 URL 字符串应包含搜索查询,则为 true,否则为 false默认值: true
    • unicode <boolean> 如果 URL 字符串的主机组件中出现的 Unicode 字符应直接编码,而不是进行 Punycode 编码,则为 true默认值: false
  • 返回: <string>

返回 WHATWG URL 对象的 URL String 表示形式的可自定义序列化。

URL 对象同时具有 toString() 方法和 href 属性,它们返回 URL 的字符串序列化。 但是,这些都不能以任何方式进行自定义。 url.format(URL[, options]) 方法允许对输出进行基本自定义。

import url from 'node:url';
const myURL = new URL('https://a:b@測試?abc#foo');

console.log(myURL.href);
// Prints https://a:b@xn--g6w251d/?abc#foo

console.log(myURL.toString());
// Prints https://a:b@xn--g6w251d/?abc#foo

console.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));
// Prints 'https://測試/?abc'const url = require('node:url');
const myURL = new URL('https://a:b@測試?abc#foo');

console.log(myURL.href);
// Prints https://a:b@xn--g6w251d/?abc#foo

console.log(myURL.toString());
// Prints https://a:b@xn--g6w251d/?abc#foo

console.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));
// Prints 'https://測試/?abc'

url.pathToFileURL(path[, options])#

  • path <string> 要转换为文件 URL 的路径。
  • options <Object>
    • windows <boolean> | <undefined> 如果 path 应该被视为 Windows 文件路径,则为 true;如果应该被视为 posix 文件路径,则为 false;如果应该使用系统默认值,则为 undefined默认值: undefined
  • 返回: <URL> 文件 URL 对象。

此函数确保 path 被绝对解析,并且在转换为文件 URL 时,URL 控制字符被正确编码。

import { pathToFileURL } from 'node:url';

new URL('/foo#1', 'file:');           // Incorrect: file:///foo#1
pathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)

new URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c
pathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)const { pathToFileURL } = require('node:url');
new URL(__filename);                  // Incorrect: throws (POSIX)
new URL(__filename);                  // Incorrect: C:\... (Windows)
pathToFileURL(__filename);            // Correct:   file:///... (POSIX)
pathToFileURL(__filename);            // Correct:   file:///C:/... (Windows)

new URL('/foo#1', 'file:');           // Incorrect: file:///foo#1
pathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)

new URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c
pathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)

url.urlToHttpOptions(url)#

  • url <URL> 要转换为选项对象的 WHATWG URL 对象。
  • 返回: <Object> 选项对象
    • protocol <string> 要使用的协议。
    • hostname <string> 要向其发出请求的服务器的域名或 IP 地址。
    • hash <string> URL 的片段部分。
    • search <string> URL 的序列化查询部分。
    • pathname <string> URL 的路径部分。
    • path <string> 请求路径。 应该包含查询字符串(如果有)。 例如 '/index.html?page=12'。 当请求路径包含非法字符时,会引发异常。 目前,只拒绝空格,但将来可能会更改。
    • href <string> 序列化的 URL。
    • port <number> 远程服务器的端口。
    • auth <string> 基本身份验证,例如 'user:password',用于计算 Authorization 标头。

此实用程序函数将 URL 对象转换为 http.request()https.request() API 所期望的普通选项对象。

import { urlToHttpOptions } from 'node:url';
const myURL = new URL('https://a:b@測試?abc#foo');

console.log(urlToHttpOptions(myURL));
/*
{
  protocol: 'https:',
  hostname: 'xn--g6w251d',
  hash: '#foo',
  search: '?abc',
  pathname: '/',
  path: '/?abc',
  href: 'https://a:b@xn--g6w251d/?abc#foo',
  auth: 'a:b'
}
*/const { urlToHttpOptions } = require('node:url');
const myURL = new URL('https://a:b@測試?abc#foo');

console.log(urlToHttpOptions(myURL));
/*
{
  protocol: 'https:',
  hostname: 'xn--g6w251d',
  hash: '#foo',
  search: '?abc',
  pathname: '/',
  path: '/?abc',
  href: 'https://a:b@xn--g6w251d/?abc#foo',
  auth: 'a:b'
}
*/

遗留 URL API#

稳定性: 3 - 遗留: 请改用 WHATWG URL API。

遗留 urlObject#

遗留 urlObject (require('node:url').Urlimport { Url } from 'node:url') 由 url.parse() 函数创建并返回。

urlObject.auth#

auth 属性是 URL 的用户名和密码部分,也称为用户信息。 此字符串子集遵循 protocol 和双斜杠(如果存在),并位于 host 组件之前,由 @ 分隔。 该字符串要么是用户名,要么是由 : 分隔的用户名和密码。

例如: 'user:pass'

urlObject.hash#

hash 属性是 URL 的片段标识符部分,包括前导 # 字符。

例如: '#hash'

urlObject.host#

host 属性是 URL 的完整的小写主机部分,包括指定的 port

例如: 'sub.example.com:8080'

urlObject.hostname#

hostname 属性是 host 组件的小写主机名部分,包含 port

例如: 'sub.example.com'

urlObject.href#

href 属性是完整的 URL 字符串,已解析,且 protocolhost 组件都转换为小写。

例如: 'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'

urlObject.path#

path 属性是 pathnamesearch 组件的串联。

例如: '/p/a/t/h?query=string'

不执行 path 的解码。

urlObject.pathname#

pathname 属性包含 URL 的整个路径部分。 这是 host(包括 port)之后和 queryhash 组件开始之前的所有内容,由 ASCII 问号 (?) 或井号 (#) 字符分隔。

例如: '/p/a/t/h'

不执行路径字符串的解码。

urlObject.port#

port 属性是 host 组件的数字端口部分。

例如: '8080'

urlObject.protocol#

protocol 属性标识 URL 的小写协议方案。

例如: 'http:'

urlObject.query#

query 属性要么是没有前导 ASCII 问号 (?) 的查询字符串,要么是 querystring 模块的 parse() 方法返回的对象。 query 属性是字符串还是对象取决于传递给 url.parse()parseQueryString 参数。

例如: 'query=string'{'query': 'string'}

如果作为字符串返回,则不执行查询字符串的解码。 如果作为对象返回,则键和值都会被解码。

urlObject.search#

search 属性包含 URL 的整个“查询字符串”部分,包括前导 ASCII 问号 (?) 字符。

例如: '?query=string'

不执行查询字符串的解码。

urlObject.slashes#

slashes 属性是一个 boolean,如果 protocol 中的冒号后需要两个 ASCII 正斜杠字符 (/),则值为 true

url.format(urlObject)#

  • urlObject <Object> | <string> 一个 URL 对象 (由 url.parse() 返回,或以其他方式构造)。如果是一个字符串,它会通过传递给 url.parse() 转换为一个对象。

url.format() 方法返回一个从 urlObject 派生的格式化 URL 字符串。

const url = require('node:url');
url.format({
  protocol: 'https',
  hostname: 'example.com',
  pathname: '/some/path',
  query: {
    page: 1,
    format: 'json',
  },
});

// => 'https://example.com/some/path?page=1&format=json' 

如果 urlObject 不是一个对象或字符串,url.format() 将抛出一个 TypeError

格式化过程如下:

  • 创建一个新的空字符串 result
  • 如果 urlObject.protocol 是一个字符串,它会被原样添加到 result
  • 否则,如果 urlObject.protocol 不是 undefined 且不是一个字符串,将会抛出一个 Error
  • 对于 urlObject.protocol 的所有字符串值,如果未以 ASCII 冒号 (:) 字符结尾,则文字字符串 : 将被附加到 result
  • 如果满足以下任一条件,则文字字符串 // 将被附加到 result
    • urlObject.slashes 属性为 true;
    • urlObject.protocolhttphttpsftpgopherfile 开头;
  • 如果 urlObject.auth 属性的值为真值,并且 urlObject.hosturlObject.hostname 都不是 undefined,则 urlObject.auth 的值将被强制转换为字符串,并附加到 result 之后跟文字字符串 @
  • 如果 urlObject.host 属性是 undefined
    • 如果 urlObject.hostname 是一个字符串,它会被附加到 result
    • 否则,如果 urlObject.hostname 不是 undefined 且不是一个字符串,将会抛出一个 Error
    • 如果 urlObject.port 属性值为真值,并且 urlObject.hostname 不是 undefined
      • 文字字符串 : 被附加到 result,并且
      • urlObject.port 的值被强制转换为字符串,并附加到 result
  • 否则,如果 urlObject.host 属性值为真值,则 urlObject.host 的值被强制转换为字符串,并附加到 result
  • 如果 urlObject.pathname 属性是一个非空字符串
    • 如果 urlObject.pathname 不是以 ASCII 正斜杠 (/) 开头,则文字字符串 '/' 被附加到 result
    • urlObject.pathname 的值被附加到 result
  • 否则,如果 urlObject.pathname 不是 undefined 且不是一个字符串,将会抛出一个 Error
  • 如果 urlObject.search 属性是 undefined 并且 urlObject.query 属性是一个 Object,则文字字符串 ? 会被附加到 result,之后是调用 querystring 模块的 stringify() 方法并将 urlObject.query 的值传递给它的输出。
  • 否则,如果 urlObject.search 是一个字符串
    • 如果 urlObject.search 的值不是以 ASCII 问号 (?) 字符开头,则文字字符串 ? 会被附加到 result
    • urlObject.search 的值被附加到 result
  • 否则,如果 urlObject.search 不是 undefined 且不是一个字符串,将会抛出一个 Error
  • 如果 urlObject.hash 属性是一个字符串
    • 如果 urlObject.hash 的值不是以 ASCII 井号 (#) 字符开头,则文字字符串 # 会被附加到 result
    • urlObject.hash 的值被附加到 result
  • 否则,如果 urlObject.hash 属性不是 undefined 且不是一个字符串,将会抛出一个 Error
  • 返回 result

url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

稳定性: 0 - 已弃用: 请改用 WHATWG URL API。

  • urlString <string> 要解析的 URL 字符串。
  • parseQueryString <boolean> 如果为 true,则 query 属性将始终设置为由 querystring 模块的 parse() 方法返回的对象。 如果为 false,则返回的 URL 对象上的 query 属性将是一个未解析、未解码的字符串。 默认: false
  • slashesDenoteHost <boolean> 如果为 true,则文字字符串 // 之后的第一个令牌,且在下一个 / 之前的,将被解释为 host。 例如,给定 //foo/bar,结果将是 {host: 'foo', pathname: '/bar'} 而不是 {pathname: '//foo/bar'}默认: false

url.parse() 方法接受一个 URL 字符串,对其进行解析,并返回一个 URL 对象。

如果 urlString 不是字符串,则会抛出一个 TypeError

如果存在 auth 属性但无法解码,则会抛出一个 URIError

url.parse() 使用宽松的、非标准的算法来解析 URL 字符串。 它容易出现安全问题,例如 主机名欺骗 以及对用户名和密码的不正确处理。 请勿将其用于不受信任的输入。 不会为 url.parse() 漏洞发布 CVE。 请改用 WHATWG URL API。

url.resolve(from, to)#

  • from <string> 如果 to 是相对 URL,则用作基本 URL。
  • to <string> 要解析的目标 URL。

url.resolve() 方法以类似于 Web 浏览器解析锚标记的方式,解析相对于基本 URL 的目标 URL。

const url = require('node:url');
url.resolve('/one/two/three', 'four');         // '/one/two/four'
url.resolve('http://example.com/', '/one');    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two'); // 'http://example.com/two' 

要使用 WHATWG URL API 获得相同的结果:

function resolve(from, to) {
  const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
  if (resolvedUrl.protocol === 'resolve:') {
    // `from` is a relative URL.
    const { pathname, search, hash } = resolvedUrl;
    return pathname + search + hash;
  }
  return resolvedUrl.toString();
}

resolve('/one/two/three', 'four');         // '/one/two/four'
resolve('http://example.com/', '/one');    // 'http://example.com/one'
resolve('http://example.com/one', '/two'); // 'http://example.com/two' 

URL 中的百分比编码#

URL 只允许包含一定范围的字符。 任何超出该范围的字符都必须进行编码。 如何编码这些字符,以及要编码哪些字符完全取决于该字符在 URL 结构中的位置。

旧版 API#

在旧版 API 中,空格 (' ') 和以下字符将在 URL 对象的属性中自动转义

< > " ` \r \n \t { } | \ ^ ' 

例如,ASCII 空格字符 (' ') 被编码为 %20。 ASCII 正斜杠 (/) 字符被编码为 %3C

WHATWG API#

WHATWG URL 标准 使用比旧版 API 更具选择性和细粒度的方法来选择编码字符。

WHATWG 算法定义了四个 "百分比编码集",描述了必须进行百分比编码的字符范围

  • C0 控制百分比编码集 包括 U+0000 到 U+001F(含)范围内的代码点以及所有大于 U+007E (~) 的代码点。

  • 片段百分比编码集 包括 C0 控制百分比编码集 以及代码点 U+0020 SPACE、U+0022 (")、U+003C (<)、U+003E (>) 和 U+0060 (`)。

  • 路径百分比编码集 包括 C0 控制百分比编码集 以及代码点 U+0020 SPACE、U+0022 (")、U+0023 (#)、U+003C (<)、U+003E (>)、U+003F (?)、U+0060 (`)、U+007B ({) 和 U+007D (})。

  • 用户信息编码集 包括 路径百分比编码集 以及代码点 U+002F (/)、U+003A (:)、U+003B (;)、U+003D (=)、U+0040 (@)、U+005B ([) 到 U+005E (^) 和 U+007C (|)。

用户信息百分比编码集 专门用于 URL 中编码的用户名和密码。 路径百分比编码集 用于大多数 URL 的路径。 片段百分比编码集 用于 URL 片段。 除了所有其他情况外,C0 控制百分比编码集 用于特定条件下的主机和路径。

当非 ASCII 字符出现在主机名中时,使用 Punycode 算法对主机名进行编码。 但是请注意,主机名可能同时包含 Punycode 编码字符和百分比编码字符

const myURL = new URL('https://%CF%80.example.com/foo');
console.log(myURL.href);
// Prints https://xn--1xa.example.com/foo
console.log(myURL.origin);
// Prints https://xn--1xa.example.com