Node.js中URL模块详解

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 模块的主要特点:

  1. 提供 URL 解析和构建功能
  2. 支持查询参数处理
  3. 提供 URL 编码和解码
  4. 支持 URL 验证和规范化
  5. 提供 URL 组件提取和操作

使用建议:

  1. 使用 URL 类处理 URL 字符串
  2. 使用 URLSearchParams 处理查询参数
  3. 注意 URL 编码和解码
  4. 验证 URL 格式
  5. 规范化 URL 路径和参数
相关推荐
gogoing3 小时前
Node.js 模块查找策略(require 完整流程)
javascript·node.js
zhangfeng11334 小时前
小龙虾 wordbuddy 安装浏览器控制器 agent-browser npm install -g agent-browse
前端·人工智能·npm·node.js
大家的林语冰5 小时前
pnpm 11 发布,弃用 JSON 和 npm CLI,进化为纯 ES6 模块,新增 pnpm pack-app 等命令,供应链保护默认启用,要求 Node
前端·javascript·node.js
会周易的程序员6 小时前
aiDgeScanner 工业设备网络扫描与管理工具
网络·c++·物联网·架构·electron·node.js·iot
阿赛工作室7 小时前
AI时代WEB开发人员生存与发展报告
前端·人工智能·node.js
会周易的程序员10 小时前
aiDgeScanner架构与实现
c++·ide·物联网·架构·node.js·aiot
whinc1 天前
Node.js技术周刊 2026年第18周
javascript·node.js