url(URL)#

稳定性: 2 - 稳定

源代码: lib/url.js

url 模块用于处理与解析 URL。 使用方法如下:

const url = require('url');

URL 字符串与 URL 对象#

URL 字符串是结构化的字符串,包含多个含义不同的组成部分。 解析字符串后返回的 URL 对象,每个属性对应字符串的各个组成部分。

url 模块提供了两套 API 来处理 URL:一个是旧版本传统的 API,一个是实现了 WHATWG标准的新 API。

WHATWG 的 API 与传统的 API 的区别如下。 在下图中,URL 'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash' 上方的是传统的 url.parse() 返回的对象的属性。 下方的则是 WHATWG 的 URL 对象的属性。

WHATWG 的 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                                              │
└────────────────────────────────────────────────────────────────────────────────────────────────┘

使用 WHATWG 的 API 解析 URL 字符串:

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

使用传统的 API 解析 URL 字符串:

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

WHATWG 的 URL 接口#

URL 类#

浏览器兼容的 URL 类,根据 WHATWG URL 标准实现。解析URL的示例可以在标准本身里边找到。

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

new URL(input[, base])#

  • input <string> 要解析的绝对或相对的 URL。如果 input 是相对路径,则需要 base。 如果 input 是绝对路径,则忽略 base
  • base <string> | <URL> 如果 input 不是绝对路径,则为要解析的基本 URL。

通过将 input 相对于 base 进行解析,创建一个新的 URL 对象。 如果 base 是一个字符串,则解析方法与 new URL(base) 相同。

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

The URL constructor is accessible as a property on the global object. It can also be imported from the built-in url module:

console.log(URL === require('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/

只有在启用 ICU 的情况下编译 node 可执行文件时,此功能才可用。 如果没有,则域名将保持不变。

如果 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);
  // 打印 #bar

myURL.hash = 'baz';
console.log(myURL.href);
  // 打印 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);
  // 打印 example.org:81

myURL.host = 'example.com:82';
console.log(myURL.href);
  // 打印 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);
  // 打印 example.org

myURL.hostname = 'example.com:82';
console.log(myURL.href);
  // 打印 https://example.com:81/foo

hostname 属性设置无效的值则会被忽略。

url.href#

获取及设置序列化的 URL。

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

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

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

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

如果给 href 属性设置的值是无效的 URL,则将会抛出 TypeError

url.origin#

获取只读的序列化的 URL 的 origin。

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

console.log(idnURL.hostname);
// 打印 xn--g6w251d

url.password#

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

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

myURL.password = '123';
console.log(myURL.href);
  // 打印 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);
  // 打印 /abc/xyz

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

分配给 pathname 属性的值中包含的无效 URL 字符是百分比编码的。 选择哪些字符进行百分比编码可能与 url.parse()url.format() 方法产生的内容有所不同。

url.port#

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

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

端口值可以是空字符串,在这种情况下,端口取决于协议/规范:

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

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

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

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

// 默认端口将自动转换为空字符。
// (HTTPS 协议默认端口是 443)
myURL.port = '443';
console.log(myURL.port);
// 打印空字符
console.log(myURL.href);
// 打印 https://example.org/

myURL.port = 1234;
console.log(myURL.port);
// 打印 1234
console.log(myURL.href);
// 输出 https://example.org:1234/

// 完全无效的端口字符串将被忽略。
myURL.port = 'abcd';
console.log(myURL.port);
// 打印 1234

// 开头的数字将会被当做端口号。
myURL.port = '5678abcd';
console.log(myURL.port);
// 打印 5678

// 非整形数字将会被截断。
myURL.port = 1234.5678;
console.log(myURL.port);
// 打印 1234

// 超出范围的数字将被忽略。
myURL.port = 1e10; // 10000000000,将按如下所述进行范围检查。
console.log(myURL.port);
// 打印 1234

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

myURL.port = 4.567e21;
console.log(myURL.port);
// 打印 4 (因为它是字符串 '4.567e21' 中的前导数字)

url.protocol#

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

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

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

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

特殊协议#

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 标准,特殊协议规范是 ftpfilegopherhttphttpswswss

url.search#

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

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

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

分配给 search 属性的值中包含的无效 URL 字符是百分比编码的。 选择哪些字符进行百分比编码可能与 url.parse()url.format() 方法产生的内容有所不同。

url.searchParams#

获取表示 URL 查询参数的 URLSearchParams 对象。 This property is read-only but the URLSearchParams object it provides can be used to mutate the URL instance; to replace the entirety of query parameters of the URL, use the url.search setter. See URLSearchParams documentation for details.

Use care when using .searchParams to modify the URL because, per the WHATWG specification, the URLSearchParams object uses different rules to determine which characters to percent-encode. For instance, the URL object will not percent encode the ASCII tilde (~) character, while URLSearchParams will always encode it:

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);
// 打印 abc

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

分配给 username 属性的值中包含的无效 URL 字符是百分比编码的。 选择哪些字符进行百分比编码可能与 url.parse()url.format() 方法产生的内容有所不同。

url.toString()#

URL 对象上调用 toString() 方法将返回序列化的 URL。 返回值与 url.hrefurl.toJSON() 的相同。

由于需要符合标准,此方法不允许用户自定义 URL 的序列化过程。 如果需要更大灵活性,require('url').format() 可能更合适。

url.toJSON()#

URL 对象上调用 toJSON() 方法将返回序列化的 URL。 返回值与 url.hrefurl.toString() 的相同。

URL 对象使用 JSON.stringify() 序列化时将自动调用该方法。

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

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'));
// 打印 123

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

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

const newSearchParams = new URLSearchParams(myURL.searchParams);
// 上面的代码等同于:
// const newSearchParams = new URLSearchParams(myURL.search);

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

// newSearchParams.toString() 会被隐式调用。
myURL.search = newSearchParams;
console.log(myURL.href);
// 打印 https://example.org/?a=b&a=c
newSearchParams.delete('a');
console.log(myURL.href);
// 打印 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'));
// 打印 'abc'
console.log(params.toString());
// 打印 'user=abc&query=xyz'

params = new URLSearchParams('?user=abc&query=xyz');
console.log(params.toString());
// 打印 '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'));
// 打印 [ 'first,second' ]
console.log(params.toString());
// 打印 'user=abc&query=first%2Csecond'

new URLSearchParams(iterable)#

  • iterable <Iterable> 元素是键值对的迭代对象。

以一种类似于 Map 的构造函数的迭代映射方式实例化一个新的 URLSearchParams 对象。 iterable 可以是一个 Array 或者任何迭代对象。 这就意味着 iterable 能够是另一个 URLSearchParams,这种情况下,构造函数将简单地根据提供的 URLSearchParams 创建一个克隆 URLSearchParamsiterable 的元素是键值对,并且其本身也可以是任何迭代对象。

允许重复的键。

let params;

// 使用数组。
params = new URLSearchParams([
  ['user', 'abc'],
  ['query', 'first'],
  ['query', 'second']
]);
console.log(params.toString());
// 打印 'user=abc&query=first&query=second'

// 使用 Map 对象。
const map = new Map();
map.set('user', 'abc');
map.set('query', 'xyz');
params = new URLSearchParams(map);
console.log(params.toString());
// 打印 'user=abc&query=xyz'

// 使用 generator 函数。
function* getQueryPairs() {
  yield ['user', 'abc'];
  yield ['query', 'first'];
  yield ['query', 'second'];
}
params = new URLSearchParams(getQueryPairs());
console.log(params.toString());
// 打印 'user=abc&query=first&query=second'

// 每个键值对必须有两个元素。
new URLSearchParams([
  ['user', 'abc', 'error']
]);
// 抛出 TypeError [ERR_INVALID_TUPLE]:
//        Each query pair must be an iterable [name, value] tuple

urlSearchParams.append(name, value)#

在查询字符串中附加一个新的键值对。

urlSearchParams.delete(name)#

删除所有键为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);
});
// 打印:
//   a b true
//   c d true

urlSearchParams.get(name)#

  • name <string>
  • 返回: <string> ,如果没有键值对对应给定的name则返回null

返回键是name的第一个键值对的值。如果没有对应的键值对,则返回null

urlSearchParams.getAll(name)#

返回键是name的所有键值对的值,如果没有满足条件的键值对,则返回一个空的数组。

urlSearchParams.has(name)#

如果存在至少一对键是 name 的键值对则返回 true

urlSearchParams.keys()#

在每一个键值对上返回一个键的 ES6 Iterator

const params = new URLSearchParams('foo=bar&foo=baz');
for (const name of params.keys()) {
  console.log(name);
}
// 打印:
//   foo
//   foo

urlSearchParams.set(name, value)#

URLSearchParams 对象中与 name 相对应的值设置为 value。 如果已经存在键为 name 的键值对,则将第一对的值设为 value 并且删除其他对。 如果不存在,则将此键值对附加在查询字符串后。

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

params.set('foo', 'def');
params.set('xyz', 'opq');
console.log(params.toString());
// 打印 foo=def&abc=def&xyz=opq

urlSearchParams.sort()#

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

该方法可以用来增加缓存命中。

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

urlSearchParams.toString()#

返回查询参数序列化后的字符串,必要时存在百分号编码字符。

urlSearchParams.values()#

在每一个键值对上返回一个值的 ES6 Iterator

urlSearchParams[Symbol.iterator]()#

根据查询字符串,返回一个键值对形式的 ES6 Iterator。 每个迭代器的项是一个 JavaScript Array。 其中, Array 的第一项是 name,第二个是 value

urlSearchParams.entries() 的别名。

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

url.domainToASCII(domain)#

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

它执行的是 url.domainToUnicode() 的逆运算。

const url = require('url');
console.log(url.domainToASCII('español.com'));
// 打印 xn--espaol-zwa.com
console.log(url.domainToASCII('中文.com'));
// 打印 xn--fiq228c.com
console.log(url.domainToASCII('xn--iñvalid.com'));
// 打印空字符串

url.domainToUnicode(domain)#

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

它执行的是 url.domainToASCII() 的逆运算。

const url = require('url');
console.log(url.domainToUnicode('xn--espaol-zwa.com'));
// 打印 español.com
console.log(url.domainToUnicode('xn--fiq228c.com'));
// 打印 中文.com
console.log(url.domainToUnicode('xn--iñvalid.com'));
// 打印空字符串

url.fileURLToPath(url)#

  • url <URL> | <string> 要转换为路径的文件 URL 字符串或者 URL 对象。
  • 返回: <string> 完全解析的平台特定的 Node.js 文件路径。

此方法保证百分号编码字符解码结果的正确性,同时也确保绝对路径字符串在不同平台下的有效性。

new URL('file:///C:/path/').pathname;    // 错误: /C:/path/
fileURLToPath('file:///C:/path/');       // 正确: C:\path\ (Windows)

new URL('file://nas/foo.txt').pathname;  // 错误: /foo.txt
fileURLToPath('file://nas/foo.txt');     // 正确: \\nas\foo.txt (Windows)

new URL('file:///你好.txt').pathname;    // 错误: /%E4%BD%A0%E5%A5%BD.txt
fileURLToPath('file:///你好.txt');       // 正确: /你好.txt (POSIX)

new URL('file:///hello world').pathname; // 错误: /hello%20world
fileURLToPath('file:///hello world');    // 正确: /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]) 方法允许输出的基本自定义。

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

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

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

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

url.pathToFileURL(path)#

  • path <string> 要转换为文件 URL 的路径。
  • 返回: <URL> 文件 URL 对象。

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

new URL(__filename);                // 错误: throws (POSIX)
new URL(__filename);                // 错误: C:\... (Windows)
pathToFileURL(__filename);          // 正确:   file:///... (POSIX)
pathToFileURL(__filename);          // 正确:   file:///C:/... (Windows)

new URL('/foo#1', 'file:');         // 错误: file:///foo#1
pathToFileURL('/foo#1');            // 正确:   file:///foo%231 (POSIX)

new URL('/some/path%.c', 'file:'); // 错误: file:///some/path%.c
pathToFileURL('/some/path%.c');    // 正确:   file:///some/path%25.c (POSIX)

传统的 URL 接口#

传统的 urlObject#

稳定性: 0 - 弃用: 改为使用 the WHATWG URL API 。

The legacy urlObject (require('url').Url) is created and returned by the url.parse() function.

urlObject.auth#

The auth property is the username and password portion of the URL, also referred to as userinfo. This string subset follows the protocol and double slashes (if present) and precedes the host component, delimited by @. The string is either the username, or it is the username and password separated by :.

For example: 'user:pass'.

urlObject.hash#

The hash property is the fragment identifier portion of the URL including the leading # character.

For example: '#hash'.

urlObject.host#

The host property is the full lower-cased host portion of the URL, including the port if specified.

For example: 'sub.example.com:8080'.

urlObject.hostname#

The hostname property is the lower-cased host name portion of the host component without the port included.

For example: 'sub.example.com'.

urlObject.href#

The href property is the full URL string that was parsed with both the protocol and host components converted to lower-case.

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

urlObject.path#

The path property is a concatenation of the pathname and search components.

For example: '/p/a/t/h?query=string'.

No decoding of the path is performed.

urlObject.pathname#

The pathname property consists of the entire path section of the URL. This is everything following the host (including the port) and before the start of the query or hash components, delimited by either the ASCII question mark (?) or hash (#) characters.

For example: '/p/a/t/h'.

No decoding of the path string is performed.

urlObject.port#

The port property is the numeric port portion of the host component.

For example: '8080'.

urlObject.protocol#

The protocol property identifies the URL's lower-cased protocol scheme.

For example: 'http:'.

urlObject.query#

The query property is either the query string without the leading ASCII question mark (?), or an object returned by the querystring module's parse() method. Whether the query property is a string or object is determined by the parseQueryString argument passed to url.parse().

For example: 'query=string' or {'query': 'string'}.

If returned as a string, no decoding of the query string is performed. If returned as an object, both keys and values are decoded.

urlObject.search#

The search property consists of the entire "query string" portion of the URL, including the leading ASCII question mark (?) character.

For example: '?query=string'.

No decoding of the query string is performed.

urlObject.slashes#

The slashes property is a boolean with a value of true if two ASCII forward-slash characters (/) are required following the colon in the protocol.

url.format(urlObject)#

稳定性: 0 - 弃用: 改为使用 the WHATWG URL API 。

  • urlObject <Object> | <string> A URL object (as returned by url.parse() or constructed otherwise). If a string, it is converted to an object by passing it to url.parse().

The url.format() method returns a formatted URL string derived from urlObject.

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

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

If urlObject is not an object or a string, url.format() will throw a TypeError.

The formatting process operates as follows:

  • A new empty string result is created.
  • If urlObject.protocol is a string, it is appended as-is to result.
  • Otherwise, if urlObject.protocol is not undefined and is not a string, an Error is thrown.
  • For all string values of urlObject.protocol that do not end with an ASCII colon (:) character, the literal string : will be appended to result.
  • If either of the following conditions is true, then the literal string // will be appended to result:
    • urlObject.slashes property is true;
    • urlObject.protocol begins with http, https, ftp, gopher, or file;
  • If the value of the urlObject.auth property is truthy, and either urlObject.host or urlObject.hostname are not undefined, the value of urlObject.auth will be coerced into a string and appended to result followed by the literal string @.
  • If the urlObject.host property is undefined then:
    • If the urlObject.hostname is a string, it is appended to result.
    • Otherwise, if urlObject.hostname is not undefined and is not a string, an Error is thrown.
    • If the urlObject.port property value is truthy, and urlObject.hostname is not undefined:
      • The literal string : is appended to result, and
      • The value of urlObject.port is coerced to a string and appended to result.
  • Otherwise, if the urlObject.host property value is truthy, the value of urlObject.host is coerced to a string and appended to result.
  • If the urlObject.pathname property is a string that is not an empty string:
    • If the urlObject.pathname does not start with an ASCII forward slash (/), then the literal string '/' is appended to result.
    • The value of urlObject.pathname is appended to result.
  • Otherwise, if urlObject.pathname is not undefined and is not a string, an Error is thrown.
  • If the urlObject.search property is undefined and if the urlObject.query property is an Object, the literal string ? is appended to result followed by the output of calling the querystring module's stringify() method passing the value of urlObject.query.
  • Otherwise, if urlObject.search is a string:
    • If the value of urlObject.search does not start with the ASCII question mark (?) character, the literal string ? is appended to result.
    • The value of urlObject.search is appended to result.
  • Otherwise, if urlObject.search is not undefined and is not a string, an Error is thrown.
  • If the urlObject.hash property is a string:
    • If the value of urlObject.hash does not start with the ASCII hash (#) character, the literal string # is appended to result.
    • The value of urlObject.hash is appended to result.
  • Otherwise, if the urlObject.hash property is not undefined and is not a string, an Error is thrown.
  • result is returned.

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

稳定性: 0 - 弃用: 改为使用 the WHATWG URL API 。

  • urlString <string> The URL string to parse.
  • parseQueryString <boolean> If true, the query property will always be set to an object returned by the querystring module's parse() method. If false, the query property on the returned URL object will be an unparsed, undecoded string. Default: false.
  • slashesDenoteHost <boolean> If true, the first token after the literal string // and preceding the next / will be interpreted as the host. For instance, given //foo/bar, the result would be {host: 'foo', pathname: '/bar'} rather than {pathname: '//foo/bar'}. Default: false.

The url.parse() method takes a URL string, parses it, and returns a URL object.

A TypeError is thrown if urlString is not a string.

A URIError is thrown if the auth property is present but cannot be decoded.

Use of the legacy url.parse() method is discouraged. Users should use the WHATWG URL API. Because the url.parse() method uses a lenient, non-standard algorithm for parsing URL strings, security issues can be introduced. Specifically, issues with host name spoofing and incorrect handling of usernames and passwords have been identified.

url.resolve(from, to)#

稳定性: 0 - 弃用: 改为使用 the WHATWG URL API 。

  • from <string> The Base URL being resolved against.
  • to <string> The HREF URL being resolved.

The url.resolve() method resolves a target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.

const url = require('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'

URL 中的百分号编码#

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

传统的接口#

在传统的 API 中,空格(' ')及以下字符将自动转义为 URL 对象的属性:

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

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

WHATWG 接口#

WHATWG URL 标志使用比传统的 API 更具选择性和更精细的方法来选择使用的编码字符。

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

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

  • 片段百分比编码集,包括 C0 控制百分比编码集,以及代码点 U+0020、U+0022、U+003C、U+003E 和 U+006。

  • 路径百分比编码集,包括 C0 控制百分比编码集,以及代码点 U+0020、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+005C、U+005D、U+005E 和 U+007C。

用户信息百分比编码集专门用于 URL 中用户名和密码部分的编码。 路径百分比编码集用于大多数 URL 的路径部分编码。 C0 控制百分比编码集则用于所有其他情况的编码,特别包括 URL 的分段部分,特殊条件下也包括主机及路径部分。

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

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