Node.js v18.18.2 文档


目录

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,另一个是实现网络浏览器所使用的相同 WHATWG URL 标准的较新 API 。

下面提供了 WHATWG 和旧版 API 之间的比较。在 URL 'https://user:[email protected]: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:[email protected]:8080/p/a/t/h?query=string#hash'); 

使用旧 API 解析 URL 字符串:

import url from 'node:url';
const myURL =
  url.parse('https://user:[email protected]:8080/p/a/t/h?query=string#hash');const url = require('node:url');
const myURL =
  url.parse('https://user:[email protected]: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不是字符串,则首先将其转换为字符串

通过解析相对于baseinput创建一个新的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,建议验证originorigin URL对象是预期的。

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:[email protected]');
console.log(myURL.password);
// Prints xyz

myURL.password = '123';
console.log(myURL.href);
// Prints https://abc:[email protected]/ 

分配给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:[email protected]');
console.log(myURL.username);
// Prints abc

myURL.username = '123';
console.log(myURL.href);
// Prints https://123:[email protected]/ 

分配给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)#

稳定性:1 - 实验性

创建一个表示给定<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对象在当前线程中注册。如果使用工作线程,则在一个工作线程中注册的Blob对象将不可用于其他工作线程或主线程。

URL.revokeObjectURL(id)#

稳定性:1 - 实验性

  • 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不是字符串,则首先将其转换为字符串
  • 返回:<布尔值>

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

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

const isNotValid = URL.canParse('/foo'); // false 

类: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>元素为键值对的可迭代对象

使用可迭代映射实例化一个新的URLSearchParams对象,其方式类似于Map的构造函数。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且值为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的名称-值对的值。如果没有这样的对,则返回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)#

  • url <网址> | <string>要转换为路径的文件 URL 字符串或 URL 对象。
  • 返回:<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 <对象>
    • 如果序列化 URL 字符串应包含用户名和密码,则为auth <boolean> true ,否则为false默认值: true
    • 如果序列化 URL 字符串应包含片段,则为fragment <boolean> true ,否则为false默认值: true
    • 如果序列化 URL 字符串应包含搜索查询,则为search <boolean> true ,否则为false默认值: true
    • unicode <boolean> true出现在 URL 字符串的主机组件中的 Unicode 字符是否应直接编码,而不是 Punycode 编码。默认值: false
  • 返回:<字符串>

返回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)#

  • path <string>要转换为文件 URL 的路径。
  • 返回:<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>请求路径。应包含查询字符串(如果有)。EG '/index.html?page=12'。当请求路径包含非法字符时抛出异常。目前,仅拒绝空格,但将来可能会改变。
    • href <string>序列化 URL。
    • port <number>远程服务器的端口。
    • auth <string>基本身份验证,即'user:password'来计算授权标头。

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

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#

稳定性:3 - 旧版:改用 WHATWG URL API。

旧版urlObjectrequire('node:url').Urlimport { Url } from 'node:url' )由url.parse()函数创建并返回。

urlObject.auth#

auth属性是 URL 的用户名和密码部分,也称为userinfo。该字符串子集位于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属性是使用转换为小写的protocolhost组件解析的完整 URL 字符串 。

例如:'http://user:[email protected]: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#

如果冒号后面需要两个 ASCII 正斜杠字符 ( / ),则 slashes属性是值为truebooleanprotocol中 。

url.format(urlObject)#

稳定性:3 - 旧版:改用 WHATWG URL API。

  • urlObject <对象> | <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
  • 对于所有不以ASCII 冒号 ( : ) 字符结尾的urlObject.protocol字符串值,文字字符串:将附加到result
  • 如果以下任一条件为真,则文字字符串// 将被附加到result
    • urlObject.slashes属性为 true;
    • urlObject.protocolhttphttpsftpgopherfile开头;
  • 如果urlObject.auth属性的值为true,并且 urlObject.hosturlObject.hostname不是undefined,则 urlObject.auth将被强制转换为字符串并附加到result 后面,后跟文字字符串@
  • 如果urlObject.host属性为undefined则:
    • 如果urlObject.hostname是字符串,则会将其附加到result
    • 否则,如果urlObject.hostname不是undefined并且不是字符串,则抛出Error
    • 如果urlObject.port属性值为 true,并且urlObject.hostname 不是undefined
      • 文字字符串:附加到result,并且
      • urlObject.port的值被强制转换为字符串并附加到 result
  • 否则,如果urlObject.host属性值为 true,则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)#

稳定性:3 - 旧版:改用 WHATWG URL API。

url.resolve()方法以类似于网络浏览器解析锚标记的方式解析相对于基本 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#

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

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

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

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

  • 路径百分比编码集包括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。

userinfo百分比编码集专门用于在 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 

NodeJS中文文档为Read dev Docs平台提供托管,中文NodeJS文档均由英文版NodeJS文档翻译,版权属于nodejs.org