Node.js 中 URL 模块全部 API 详解
1. URL 类
javascript
const { URL } = require('url');
// 1. 创建 URL 对象
const url = new URL('https://www.example.com:8080/path?query=value#hash');
// 2. URL 属性
console.log('协议:', url.protocol); // 'https:'
console.log('主机名:', url.hostname); // 'www.example.com'
console.log('端口:', url.port); // '8080'
console.log('主机:', url.host); // 'www.example.com:8080'
console.log('路径:', url.pathname); // '/path'
console.log('查询字符串:', url.search); // '?query=value'
console.log('查询参数:', url.searchParams); // URLSearchParams 对象
console.log('哈希:', url.hash); // '#hash'
console.log('完整 URL:', url.href); // 'https://www.example.com:8080/path?query=value#hash'
console.log('源:', url.origin); // 'https://www.example.com'
console.log('用户名:', url.username); // ''
console.log('密码:', url.password); // ''
// 3. 修改 URL 属性
url.protocol = 'http:';
url.hostname = 'example.com';
url.port = '80';
url.pathname = '/new-path';
url.search = '?new=query';
url.hash = '#new-hash';
url.username = 'user';
url.password = 'pass';
// 4. URL 字符串化
console.log('URL 字符串:', url.toString());
console.log('URL JSON:', url.toJSON());
2. URLSearchParams 类
javascript
const { URLSearchParams } = require('url');
// 1. 创建 URLSearchParams 对象
const params = new URLSearchParams('key1=value1&key2=value2');
// 2. 添加参数
params.append('key3', 'value3');
params.append('key3', 'value4'); // 可以添加同名参数
// 3. 获取参数
console.log('获取参数:', params.get('key1')); // 'value1'
console.log('获取所有参数:', params.getAll('key3')); // ['value3', 'value4']
// 4. 检查参数是否存在
console.log('参数是否存在:', params.has('key1')); // true
// 5. 删除参数
params.delete('key2');
// 6. 设置参数
params.set('key1', 'new-value'); // 替换已存在的参数
// 7. 遍历参数
for (const [key, value] of params) {
console.log(`${key}: ${value}`);
}
// 8. 转换为字符串
console.log('参数字符串:', params.toString());
// 9. 排序参数
params.sort();
// 10. 清空参数
params.forEach((value, key) => {
params.delete(key);
});
3. URL 解析和格式化
javascript
const { URL, URLSearchParams } = require('url');
// 1. 解析 URL
function parseURL(urlString) {
try {
const url = new URL(urlString);
return {
protocol: url.protocol,
hostname: url.hostname,
port: url.port,
pathname: url.pathname,
search: url.search,
hash: url.hash,
username: url.username,
password: url.password,
origin: url.origin
};
} catch (error) {
console.error('URL 解析错误:', error);
return null;
}
}
// 2. 构建 URL
function buildURL(options) {
const url = new URL('https://example.com');
if (options.protocol) url.protocol = options.protocol;
if (options.hostname) url.hostname = options.hostname;
if (options.port) url.port = options.port;
if (options.pathname) url.pathname = options.pathname;
if (options.search) url.search = options.search;
if (options.hash) url.hash = options.hash;
if (options.username) url.username = options.username;
if (options.password) url.password = options.password;
return url.toString();
}
// 3. 解析查询字符串
function parseQueryString(queryString) {
const params = new URLSearchParams(queryString);
const result = {};
for (const [key, value] of params) {
result[key] = value;
}
return result;
}
// 4. 构建查询字符串
function buildQueryString(params) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
searchParams.append(key, value);
}
return searchParams.toString();
}
4. URL 验证和规范化
javascript
const { URL } = require('url');
// 1. 验证 URL
function isValidURL(urlString) {
try {
new URL(urlString);
return true;
} catch (error) {
return false;
}
}
// 2. 规范化 URL
function normalizeURL(urlString) {
try {
const url = new URL(urlString);
// 移除默认端口
if (url.port === '80' && url.protocol === 'http:') {
url.port = '';
}
if (url.port === '443' && url.protocol === 'https:') {
url.port = '';
}
// 规范化路径
url.pathname = url.pathname.replace(/\/+/g, '/');
if (url.pathname !== '/' && url.pathname.endsWith('/')) {
url.pathname = url.pathname.slice(0, -1);
}
return url.toString();
} catch (error) {
return urlString;
}
}
// 3. 解析相对 URL
function resolveURL(base, relative) {
try {
return new URL(relative, base).toString();
} catch (error) {
return null;
}
}
// 4. 提取 URL 组件
function extractURLComponents(urlString) {
try {
const url = new URL(urlString);
return {
protocol: url.protocol.replace(':', ''),
domain: url.hostname,
port: url.port || (url.protocol === 'https:' ? '443' : '80'),
path: url.pathname,
query: url.search.slice(1),
hash: url.hash.slice(1)
};
} catch (error) {
return null;
}
}
5. URL 编码和解码
javascript
const { URL, URLSearchParams } = require('url');
// 1. URL 编码
function encodeURL(urlString) {
try {
const url = new URL(urlString);
return url.toString();
} catch (error) {
return encodeURI(urlString);
}
}
// 2. URL 解码
function decodeURL(urlString) {
try {
return decodeURI(urlString);
} catch (error) {
return urlString;
}
}
// 3. 参数编码
function encodeParams(params) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
searchParams.append(key, value);
}
return searchParams.toString();
}
// 4. 参数解码
function decodeParams(queryString) {
const params = new URLSearchParams(queryString);
const result = {};
for (const [key, value] of params) {
result[key] = value;
}
return result;
}
6. URL 操作工具
javascript
const { URL, URLSearchParams } = require('url');
// 1. URL 合并
function mergeURLs(base, relative) {
try {
return new URL(relative, base).toString();
} catch (error) {
return null;
}
}
// 2. URL 比较
function compareURLs(url1, url2) {
try {
const u1 = new URL(url1);
const u2 = new URL(url2);
return {
sameProtocol: u1.protocol === u2.protocol,
sameHost: u1.host === u2.host,
samePath: u1.pathname === u2.pathname,
sameQuery: u1.search === u2.search,
sameHash: u1.hash === u2.hash,
isEqual: u1.href === u2.href
};
} catch (error) {
return null;
}
}
// 3. URL 转换
function transformURL(urlString, options) {
try {
const url = new URL(urlString);
if (options.protocol) url.protocol = options.protocol;
if (options.hostname) url.hostname = options.hostname;
if (options.port) url.port = options.port;
if (options.pathname) url.pathname = options.pathname;
if (options.search) url.search = options.search;
if (options.hash) url.hash = options.hash;
return url.toString();
} catch (error) {
return null;
}
}
// 4. URL 验证器
class URLValidator {
constructor(options = {}) {
this.options = {
protocols: ['http:', 'https:'],
requireProtocol: true,
...options
};
}
validate(urlString) {
try {
const url = new URL(urlString);
if (this.options.requireProtocol && !url.protocol) {
return false;
}
if (this.options.protocols && !this.options.protocols.includes(url.protocol)) {
return false;
}
return true;
} catch (error) {
return false;
}
}
}
7. 实际应用示例
javascript
const { URL, URLSearchParams } = require('url');
// 1. URL 路由解析器
class URLRouter {
constructor() {
this.routes = new Map();
}
addRoute(pattern, handler) {
this.routes.set(pattern, handler);
}
match(urlString) {
const url = new URL(urlString);
const pathname = url.pathname;
for (const [pattern, handler] of this.routes) {
const regex = new RegExp(pattern);
if (regex.test(pathname)) {
return {
handler,
params: this.extractParams(pattern, pathname),
query: Object.fromEntries(url.searchParams)
};
}
}
return null;
}
extractParams(pattern, pathname) {
const params = {};
const patternParts = pattern.split('/');
const pathParts = pathname.split('/');
for (let i = 0; i < patternParts.length; i++) {
if (patternParts[i].startsWith(':')) {
const paramName = patternParts[i].slice(1);
params[paramName] = pathParts[i];
}
}
return params;
}
}
// 2. URL 参数处理器
class URLParamHandler {
constructor() {
this.params = new URLSearchParams();
}
setParams(params) {
for (const [key, value] of Object.entries(params)) {
this.params.set(key, value);
}
}
getParams() {
return Object.fromEntries(this.params);
}
removeParam(key) {
this.params.delete(key);
}
clearParams() {
this.params = new URLSearchParams();
}
toString() {
return this.params.toString();
}
}
// 3. URL 重写器
class URLRewriter {
constructor(rules) {
this.rules = rules;
}
rewrite(urlString) {
const url = new URL(urlString);
for (const rule of this.rules) {
if (rule.pattern.test(url.pathname)) {
url.pathname = url.pathname.replace(rule.pattern, rule.replacement);
}
}
return url.toString();
}
}
// 4. URL 监控器
class URLMonitor {
constructor() {
this.history = new Map();
}
track(urlString) {
const url = new URL(urlString);
const key = url.origin + url.pathname;
if (!this.history.has(key)) {
this.history.set(key, {
count: 0,
lastAccess: null,
params: new Map()
});
}
const entry = this.history.get(key);
entry.count++;
entry.lastAccess = new Date();
for (const [key, value] of url.searchParams) {
if (!entry.params.has(key)) {
entry.params.set(key, new Set());
}
entry.params.get(key).add(value);
}
}
getStats() {
const stats = [];
for (const [url, data] of this.history) {
stats.push({
url,
count: data.count,
lastAccess: data.lastAccess,
params: Object.fromEntries(
Array.from(data.params.entries()).map(([key, values]) => [
key,
Array.from(values)
])
)
});
}
return stats;
}
}
URL 模块的主要特点:
- 提供 URL 解析和构建功能
- 支持查询参数处理
- 提供 URL 编码和解码
- 支持 URL 验证和规范化
- 提供 URL 组件提取和操作
使用建议:
- 使用 URL 类处理 URL 字符串
- 使用 URLSearchParams 处理查询参数
- 注意 URL 编码和解码
- 验证 URL 格式
- 规范化 URL 路径和参数