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 路径和参数
相关推荐
avoidaily6 小时前
使用Node.js分片上传大文件到阿里云OSS
阿里云·node.js·云计算
xd000026 小时前
8.axios Http网络请求库(1)
node.js
孟孟~7 小时前
npm run dev 报错:Error: error:0308010C:digital envelope routines::unsupported
前端·npm·node.js
孟孟~7 小时前
npm install 报错:npm error: ...node_modules\deasync npm error command failed
前端·npm·node.js
CUIYD_198911 小时前
Vue 中组件命名与引用
javascript·vue.js·node.js
全栈技术负责人11 小时前
Webpack性能优化:构建速度与体积优化策略
前端·webpack·node.js
程序猿小D16 小时前
第14节 Node.js 全局对象
linux·前端·npm·node.js·编辑器·vim
IT瘾君1 天前
JavaWeb:前端工程化-ElementPlus
前端·elementui·node.js·vue
早知道不学Java了1 天前
chromedriver 下载失败
前端·vue.js·react.js·npm·node.js
贩卖纯净水.1 天前
Webpack搭建本地服务器
前端·webpack·node.js