NodeJs-URL

 后端   小卒子   2024-09-11 09:24   218
  nodejs

Node.js 的 url 模块提供了用于解析 URL(统一资源定位符)、格式化 URL、解析查询字符串等的工具。它支持各种协议(如 HTTP、HTTPS、FTP 等),并且可以将 URL 字符串解析为其组成部分。以下是 url 模块的相关属性、方法及其详尽的使用说明,涵盖了模块的各个方面。


1. 引入 url 模块

首先,通过 require 引入 url 模块:

const url = require('url');

自 Node.js v7 以后,还可以使用 WHATWG URL 标准,这种方式对 URL 解析的处理方式更接近浏览器标准。以下会分别介绍两种 API。


2. URL 解析

url.parse() 是 Node.js 提供的传统 URL 解析方法,用于将 URL 字符串解析为 URL 对象。

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

  • urlString:要解析的 URL 字符串。
  • parseQueryString:如果为 true,则会将查询字符串解析为对象。默认为 false
  • slashesDenoteHost:如果为 true,即使没有协议前缀,也会将双斜杠后的部分解析为 host。默认为 false

示例:

const url = require('url');

const parsedUrl = url.parse('https://example.com:8080/path?name=abc&age=30#hash', true);
console.log(parsedUrl);

输出结果:

Url {
  protocol: 'https:',
  slashes: true,
  auth: null,
  host: 'example.com:8080',
  port: '8080',
  hostname: 'example.com',
  hash: '#hash',
  search: '?name=abc&age=30',
  query: { name: 'abc', age: '30' },  // 如果第二个参数为 true,则 query 会被解析为对象
  pathname: '/path',
  path: '/path?name=abc&age=30',
  href: 'https://example.com:8080/path?name=abc&age=30#hash'
}

说明:

  • protocol:协议,如 http:, https:
  • slashes:如果协议后有双斜杠(//),该值为 true
  • host:主机名与端口号(如果有)。
  • port:端口号。
  • hostname:主机名。
  • hash:URL 中的片段标识符(# 之后的部分)。
  • search:查询字符串(包括问号 ?)。
  • query:解析后的查询参数对象或字符串(取决于 parseQueryString 参数)。
  • pathname:URL 的路径部分。
  • path:路径与查询字符串的组合。
  • href:完整的 URL 字符串。

2.2 URL.parse() 示例 - slashesDenoteHost 参数

如果没有协议时,也可以将双斜杠后的部分解析为 host

const parsedUrl = url.parse('//example.com/path', false, true);
console.log(parsedUrl.host);  // 输出: 'example.com'

3. URL 解析的新 API (WHATWG URL)

自 Node.js v7 开始,Node.js 提供了一个符合 WHATWG 标准的 URL 类,这种方式与现代浏览器的行为更加一致。

3.1 new URL(input, [base])

  • input:要解析的 URL 字符串。
  • base:可选的基准 URL。如果 input 是相对 URL,则需要提供基准 URL。

示例:

const { URL } = require('url');

const myUrl = new URL('https://example.com:8080/path?name=abc&age=30#hash');
console.log(myUrl);

输出结果:

URL {
  href: 'https://example.com:8080/path?name=abc&age=30#hash',
  origin: 'https://example.com:8080',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'example.com:8080',
  hostname: 'example.com',
  port: '8080',
  pathname: '/path',
  search: '?name=abc&age=30',
  searchParams: URLSearchParams { 'name' => 'abc', 'age' => '30' },
  hash: '#hash'
}

3.2 相对 URL 和基准 URL

如果 input 是相对 URL,必须提供 base 作为基准:

const { URL } = require('url');

const myUrl = new URL('/path', 'https://example.com');
console.log(myUrl.href);  // 输出: 'https://example.com/path'

4. URL 格式化

4.1 url.format(urlObject)

将 URL 对象或 WHATWG URL 实例格式化为字符串。

const url = require('url');

const urlObject = {
  protocol: 'https:',
  host: 'example.com',
  pathname: '/path',
  query: { name: 'abc', age: 30 }
};

const formattedUrl = url.format(urlObject);
console.log(formattedUrl);  // 输出: 'https://example.com/path?name=abc&age=30'

4.2 WHATWG URL 格式化

WHATWG URL 实例的 toString()href 属性也可以格式化 URL:

const { URL } = require('url');

const myUrl = new URL('https://example.com/path?name=abc');
console.log(myUrl.href);        // 输出: 'https://example.com/path?name=abc'
console.log(myUrl.toString());  // 输出: 'https://example.com/path?name=abc'

5. URL 查询参数处理

5.1 url.parse() 处理查询字符串

如果 url.parse() 的第二个参数为 true,查询字符串会被解析为对象:

const parsedUrl = url.parse('https://example.com/path?name=abc&age=30', true);
console.log(parsedUrl.query);  // 输出: { name: 'abc', age: '30' }

5.2 WHATWG URLSearchParams

WHATWG URL 标准引入了 URLSearchParams 类,可以更方便地处理查询参数。

创建 URLSearchParams
const { URLSearchParams } = require('url');

const params = new URLSearchParams('name=abc&age=30');
console.log(params.get('name'));  // 输出: 'abc'
console.log(params.get('age'));   // 输出: '30'
添加、修改和删除参数
const params = new URLSearchParams();
params.append('name', 'abc');
params.append('age', '30');
params.set('age', '31');  // 修改参数
params.delete('name');    // 删除参数
console.log(params.toString());  // 输出: 'age=31'

5.3 searchParams 在 WHATWG URL 中使用

WHATWG URL 实例自动提供 searchParams 属性,用于处理查询参数:

const { URL } = require('url');

const myUrl = new URL('https://example.com/path?name=abc&age=30');
console.log(myUrl.searchParams.get('name'));  // 输出: 'abc'

myUrl.searchParams.append('city', 'New York');
console.log(myUrl.toString());  // 输出: 'https://example.com/path?name=abc&age=30&city=New+York'

6. URL 解析中的其他方法

6.1 url.resolve(from, to)

将相对 URL to 基于 from 解析为绝对 URL。这种方法类似于浏览器中处理相对路径的方法。

const resolvedUrl = url.resolve('https://example.com/dir/', 'sub');
console.log(resolvedUrl);  // 输出: 'https://example.com/dir/sub'

如果 to 是绝对路径,它会替换掉 from 的路径部分:

const resolvedUrl = url.resolve('https://example.com/dir/', '/other');
console.log(resolvedUrl);  // 输出: 'https://example.com/other'

7. API 的区别与适用场景

  • url.parse()url.format():适用于传统的 URL 处理场景,尤其是在 Node.js v7 之前使用较多。
  • WHATWG URL API:更符合现代 Web 标准,推荐在 Node.js v10+ 的项目中使用,提供了更灵活、强大的 URL 处理方式。
  • url.parse() 是 Node.js 提供的传统方法,它

将 URL 解析为对象,适合处理简单的 URL 场景。

  • new URL() 是 WHATWG 标准的一部分,它提供了更符合现代浏览器的解析方式,适合处理复杂的、基于标准的 URL。

总结

Node.js url 模块无论是传统的 API 还是 WHATWG 标准 API 都提供了丰富的功能,能够满足绝大多数场景的需求。在处理 URL 时,根据需求选择合适的解析方式,并在复杂项目中建议使用 WHATWG 标准,以保证与浏览器端一致的行为。