网址字符串与网址对象
网址字符串是包含多个有意义组件的结构化字符串。 解析时,将返回包含每个组件的属性的网址对象。
url
模块提供了两种用于处理网址的 API:一种是 Node.js 特定的旧版 API,一种是实现了与 Web 浏览器使用的相同的 WHATWG 网址标准的新版 API。
下面提供了 WHATWG 和 旧版 API 之间的比较。 在网址 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'
上方显示的是由旧版 url.parse()
返回的对象的属性。 下方则是 WHATWG URL
对象的属性。
WHATWG 网址的 origin
属性包括 protocol
和 host
,但不包括 username
或 password
。
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 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 解析网址字符串:
const myURL =new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
console.log(myURL);
// URL {
// href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash',
// origin: 'https://sub.example.com:8080',
// protocol: 'https:',
// username: 'user',
// password: 'pass',
// host: 'sub.example.com:8080',
// hostname: 'sub.example.com',
// port: '8080',
// pathname: '/p/a/t/h',
// search: '?query=string',
// searchParams: URLSearchParams { 'query' => 'string' },
// hash: '#hash'
// }
使用旧版 API 解析网址字符串:
import url from 'url';
const myURL = url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
console.log(myURL);
// Url {
// protocol: 'https:',
// slashes: true,
// auth: 'user:pass',
// host: 'sub.example.com:8080',
// port: '8080',
// hostname: 'sub.example.com',
// hash: '#hash',
// search: '?query=string',
// query: 'query=string',
// pathname: '/p/a/t/h',
// path: '/p/a/t/h?query=string',
// href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'
// }
new URL
new URL(input[, base])
input
<string>要解析的绝对或相对的输入网址。 如果input
是相对的,则需要base
。 如果input
是绝对的,则忽略base
。base
<string> 如果input
不是绝对的,则为要解析的基本网址。
通过相对于 base
解析 input
来创建新的 URL
对象。 如果 base
作为字符串传入,则其将被解析为等效于 new URL(base)
。
const myURL = new URL('/foo', 'https://example.org/');
// https://example.org/foo
网址构造函数可作为全局对象的属性访问。 也可以从内置的 url 模块中导入:
import { URL } from 'url';
console.log(URL === globalThis.URL); // 打印 'true'.
URLSearchParams 类
URLSearchParams
API 提供对 URL
查询的读写访问。 URLSearchParams
类也可以与以下四个构造函数之一单独使用。 URLSearchParams
类也在全局对象上可用。
WHATWG URLSearchParams
接口和 querystring
模块具有相似的用途,但 querystring
模块的用途更通用,因为它允许自定义的分隔符(&
和 =
)。 换句话说,此 API 纯粹是为网址查询字符串而设计。
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
url.parse
url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
-
urlString
<string> 要解析的 URL 字符串。 -
parseQueryString
<boolean> 如果为true
,则query
属性将始终设置为querystring
模块的parse()
方法返回的对象。 如果为false
,则返回的网址对象上的query
属性将是未解析、未解码的字符串。 默认值:false
。 -
slashesDenoteHost
<boolean> 如果为true
,则文字串//
之后和下一个/
之前的第一个令牌将被解释为host
。 例如,给定//foo/bar
,结果将是{host: 'foo', pathname: '/bar'}
而不是{pathname: '//foo/bar'}
。 默认值:false
。
url.parse()
方法接受网址字符串,解析并返回网址对象。
如果 urlString
不是字符串,则抛出 TypeError
。
如果 auth
属性存在但无法解码,则抛出 URIError
。
不鼓励使用旧版的 url.parse()
方法。 用户应使用 WHATWG URL
API。 由于 url.parse()
方法使用一种宽松的非标准算法来解析网址字符串,因此可能会引入安全问题。 具体来说,已经确定了主机名欺骗以及用户名和密码处理不当的问题。
url.format
url.format(URL[, options])
URL
<URL> WHATWG 网址对象options
<Object>auth
<boolean>序列化的网址字符串是否包含用户名和密码,则为true
,否则为false
。 默认值:true
。fragment
<boolean> 序列化的网址字符串是否包含片段hash,则为true
,否则为false
。 默认值:true
。search
<boolean> 序列化的网址字符串是否包含搜索查询,则为true
,否则为false
。 默认值:true
。unicode
<boolean>true
如果出现在网址字符串的主机组件中的 Unicode 字符应该被直接编码而不是 Punycode 编码。 默认值:false
。
- 返回: <string>
返回 WHATWG 网址对象的网址 String
表示的可自定义的序列化。
网址对象具有 toString()
方法和 href
属性,用于返回网址的字符串序列化。 但是,这些都不能以任何方式自定义。 url.format(URL[, options])
方法允许对输出进行基本的自定义。
import url from 'url';
const myURL = new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
console.log(myURL);
// 打印
// URL {
// href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash',
// origin: 'https://sub.example.com:8080',
// protocol: 'https:',
// username: 'user',
// password: 'pass',
// host: 'sub.example.com:8080',
// hostname: 'sub.example.com',
// port: '8080',
// pathname: '/p/a/t/h',
// search: '?query=string',
// searchParams: URLSearchParams { 'query' => 'string' },
// hash: '#hash'
// }
console.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));
// 打印 https://sub.example.com:8080/p/a/t/h?query=string
url.resolve
url.resolve(from, to)
-
from
正在解析的基本网址。 -
to
正在解析的 HREF 网址。
url.resolve()
方法以类似于 Web 浏览器解析锚标记 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'
可以使用 WHATWG 网址 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'