Rust URL处理库deno_url的使用,高效解析和操作URL字符串

Rust URL处理库deno_url的使用,高效解析和操作URL字符串

deno_url是一个实现了URL和URLPattern API的Rust库,主要用于Deno运行时。

使用示例

从JavaScript中,包含扩展的源文件,并将URLURLPatternURLSearchParams赋值给全局作用域:

import * as url from "ext:deno_url/00_url.js";
import * as urlPattern from "ext:deno_url/01_urlpattern.js";

Object.defineProperty(globalThis, "URL", {
  value: url.URL,
  enumerable: false,
  configurable: true,
  writable: true,
});

Object.defineProperty(globalThis, "URLPattern", {
  value: url.URLPattern,
  enumerable: false,
  configurable: true,
  writable: true,
});

Object.defineProperty(globalThis, "URLSearchParams", {
  value: url.URLSearchParams,
  enumerable: false,
  configurable: true,
  writable: true,
});

然后在Rust中,在RuntimeOptionsextensions字段中提供deno_url::deno_url::init()

完整Rust示例

下面是一个完整的Rust示例,展示如何使用deno_url库来解析和操作URL:

use deno_url::Url;

fn main() {
    // 解析URL
    let url_str = "https://example.com/path/to/resource?query=123#fragment";
    let parsed_url = Url::parse(url_str).expect("Failed to parse URL");
    
    // 获取URL各部分
    println!("Scheme: {}", parsed_url.scheme());
    println!("Host: {}", parsed_url.host_str().unwrap());
    println!("Path: {}", parsed_url.path());
    println!("Query: {:?}", parsed_url.query());
    println!("Fragment: {:?}", parsed_url.fragment());
    
    // 修改URL部分
    let mut modified_url = parsed_url.clone();
    modified_url.set_path("/new/path");
    modified_url.set_query(Some("new_query=456"));
    
    println!("Modified URL: {}", modified_url);
    
    // 处理URL搜索参数
    let search_params = parsed_url.search_params();
    for (key, value) in search_params {
        println!("Query param: {} = {}", key, value);
    }
    
    // 创建新的URL
    let base_url = Url::parse("https://example.com/base").unwrap();
    let relative_url = "relative/path";
    let resolved_url = base_url.join(relative_url).unwrap();
    println!("Resolved URL: {}", resolved_url);
}

提供的操作

deno_url提供了以下操作,可以通过Deno.ops访问:

  • op_url_reparse
  • op_url_parse
  • op_url_get_serialization
  • op_url_parse_with_base
  • op_url_parse_search_params
  • op_url_stringify_search_params
  • op_urlpattern_parse
  • op_urlpattern_process_match_input

依赖

  • deno_webidl: 由deno_webidl crate提供

安装

将以下内容添加到你的Cargo.toml中:

deno_url = "0.213.0"

或者运行以下命令:

cargo add deno_url

deno_url库遵循MIT许可证发布。

完整示例demo

以下是一个更完整的示例,展示deno_url库的各种功能:

use deno_url::{Url, UrlSearchParams};

fn main() {
    // 示例1: 基本URL解析
    let url = Url::parse("https://user:pass@example.com:8080/path?query=1#frag")
        .expect("Failed to parse URL");
    
    println!("完整URL: {}", url);
    println!("协议: {}", url.scheme());
    println!("用户名: {}", url.username());
    println!("密码: {}", url.password().unwrap_or(""));
    println!("主机: {}", url.host_str().unwrap());
    println!("端口: {}", url.port().unwrap_or(0));
    println!("路径: {}", url.path());
    println!("查询字符串: {:?}", url.query());
    println!("片段: {:?}", url.fragment());

    // 示例2: 修改URL
    let mut mutable_url = url.clone();
    mutable_url.set_scheme("http").expect("无效的协议");
    mutable_url.set_username("newuser").expect("设置用户名失败");
    mutable_url.set_password(Some("newpass")).expect("设置密码失败");
    mutable_url.set_host("newexample.com").expect("设置主机失败");
    mutable_url.set_port(Some(9090)).expect("设置端口失败");
    mutable_url.set_path("/newpath");
    mutable_url.set_query(Some("newquery=2"));
    mutable_url.set_fragment(Some("newfrag"));
    
    println!("修改后的URL: {}", mutable_url);

    // 示例3: 处理查询参数
    let search_url = Url::parse("https://example.com/?name=John&age=30&city=NY")
        .expect("解析失败");
    
    let params = search_url.search_params();
    println!("原始查询参数:");
    for (k, v) in params.iter() {
        println!("{}: {}", k, v);
    }

    // 修改查询参数
    let mut new_params = UrlSearchParams::new();
    new_params.append("name", "Mike");
    new_params.append("age", "35");
    new_params.append("country", "US");
    
    let mut modified_url = search_url.clone();
    modified_url.set_search(Some(&new_params.to_string()));
    println!("修改后的查询参数URL: {}", modified_url);

    // 示例4: URL拼接
    let base = Url::parse("https://example.com/dir/").unwrap();
    let joined = base.join("subdir/file.html").unwrap();
    println!("拼接后的URL: {}", joined);

    // 示例5: 规范化URL
    let normalized = Url::parse("https://example.com/./a/../b/").unwrap();
    println!("规范化后的URL: {}", normalized);
}

1 回复

Rust URL处理库deno_url的使用指南

介绍

deno_url是Rust中一个高效且符合标准的URL解析和操作库,它源自Deno项目的URL处理实现。这个库提供了符合WHATWG URL标准的解析功能,支持各种URL操作,包括解析、序列化、修改URL各部分等。

主要特性

  • 符合WHATWG URL标准
  • 高性能解析
  • 支持相对URL解析
  • 完整的URL组成部分访问和修改
  • 支持IDNA(国际化域名)
  • 严格的错误处理

使用方法

首先在Cargo.toml中添加依赖:

[dependencies]
deno_url = "0.4"

基本URL解析

use deno_url::Url;

fn main() {
    let url = Url::parse("https://www.example.com/path?query=123#fragment").unwrap();
    
    println!("Scheme: {}", url.scheme());
    println!("Host: {}", url.host_str().unwrap());
    println!("Path: {}", url.path());
    println!("Query: {:?}", url.query());
    println!("Fragment: {:?}", url.fragment());
}

构建URL

use deno_url::Url;

fn main() {
    let mut url = Url::parse("https://example.com").unwrap();
    url.set_path("/api/v1/users");
    url.set_query(Some("page=2&limit=10"));
    
    println!("Constructed URL: {}", url);
}

相对URL解析

use deno_url::Url;

fn main() {
    let base = Url::parse("https://example.com/api/v1").unwrap();
    let relative = "../v2/users";
    
    let resolved = base.join(&relative).unwrap();
    println!("Resolved URL: {}", resolved); // 输出: https://example.com/api/v2/users
}

URL验证

use deno_url::Url;

fn main() {
    match Url::parse("not a valid url") {
        Ok(url) => println!("Valid URL: {}", url),
        Err(e) => println!("Invalid URL: {}", e),
    }
}

修改URL各部分

use deno_url::Url;

fn main() {
    let mut url = Url::parse("https://example.com/old/path").unwrap();
    
    // 修改协议
    url.set_scheme("http").unwrap();
    
    // 修改主机
    url.set_host(Some("newexample.com")).unwrap();
    
    // 修改端口
    url.set_port(Some(8080)).unwrap();
    
    // 修改路径
    url.set_path("/new/path");
    
    println!("Modified URL: {}", url);
}

处理查询参数

use deno_url::Url;

fn main() {
    let mut url = Url::parse("https://example.com/search").unwrap();
    
    // 添加查询参数
    url.query_pairs_mut()
        .append_pair("q", "rust programming")
        .append_pair("lang", "en");
    
    println!("URL with query: {}", url);
    
    // 解析查询参数
    let query: Vec<(String, String)> = url.query_pairs().into_owned().collect();
    println!("Query pairs: {:?}", query);
}

性能提示

deno_url在解析URL时已经做了大量优化,但以下做法可以进一步提高性能:

  1. 重用Url对象而不是重复创建
  2. 对于已知有效的URL,可以使用unwrap()而不是模式匹配
  3. 批量修改URL属性而不是多次单独修改

错误处理

deno_url提供了详细的错误信息,建议在生产代码中妥善处理错误:

use deno_url::{Url, ParseError};

fn parse_url(input: &str) -> Result<Url, ParseError> {
    Url::parse(input)
}

fn main() {
    match parse_url("invalid url") {
        Ok(url) => println!("Parsed URL: {}", url),
        Err(e) => println!("Error parsing URL: {}", e),
    }
}

完整示例代码

use deno_url::{Url, ParseError};

fn main() {
    // 示例1: 基本URL解析
    println!("=== 基本URL解析 ===");
    let url = Url::parse("https://www.example.com:8080/path/to/resource?name=ferret&color=purple#section1").unwrap();
    println!("完整URL: {}", url);
    println!("协议: {}", url.scheme());
    println!("主机: {}", url.host_str().unwrap());
    println!("端口: {:?}", url.port());
    println!("路径: {}", url.path());
    println!("查询字符串: {:?}", url.query());
    println!("片段: {:?}", url.fragment());
    println!();

    // 示例2: 构建URL
    println!("=== 构建URL ===");
    let mut url = Url::parse("https://api.example.com").unwrap();
    url.set_path("/v2/users");
    url.set_query(Some("page=1&per_page=20"));
    println!("构建的URL: {}", url);
    println!();

    // 示例3: 相对URL解析
    println!("=== 相对URL解析 ===");
    let base = Url::parse("https://example.com/docs/tutorial").unwrap();
    let relative = "../reference/guide";
    let resolved = base.join(relative).unwrap();
    println!("解析后的URL: {}", resolved);
    println!();

    // 示例4: URL验证
    println!("=== URL验证 ===");
    match Url::parse("htp://invalid url") {
        Ok(url) => println!("有效的URL: {}", url),
        Err(e) => println!("URL解析错误: {}", e),
    }
    println!();

    // 示例5: 修改URL
    println!("=== 修改URL ===");
    let mut url = Url::parse("https://old.example.com:8080/old/path").unwrap();
    url.set_scheme("http").unwrap();
    url.set_host(Some("new.example.com")).unwrap();
    url.set_port(None).unwrap(); // 移除端口
    url.set_path("/new/path");
    url.set_query(Some("param=value"));
    println!("修改后的URL: {}", url);
    println!();

    // 示例6: 查询参数处理
    println!("=== 查询参数处理 ===");
    let mut url = Url::parse("https://search.example.com").unwrap();
    {
        let mut pairs = url.query_pairs_mut();
        pairs.append_pair("q", "Rust编程");
        pairs.append_pair("sort", "desc");
        pairs.append_pair("page", "1");
    }
    println!("带查询参数的URL: {}", url);
    
    // 解析查询参数
    let query_pairs: Vec<_> = url.query_pairs().collect();
    println!("查询参数键值对:");
    for (key, value) in query_pairs {
        println!("  {}: {}", key, value);
    }
    println!();

    // 示例7: 错误处理
    println!("=== 错误处理 ===");
    fn process_url(url_str: &str) -> Result<(), ParseError> {
        let url = Url::parse(url_str)?;
        println!("成功解析URL: {}", url);
        Ok(())
    }

    match process_url("https://valid.url") {
        Ok(_) => println!("URL处理成功"),
        Err(e) => println!("URL处理失败: {}", e),
    }

    match process_url(":invalid.url") {
        Ok(_) => println!("URL处理成功"),
        Err(e) => println!("URL处理失败: {}", e),
    }
}

这个完整示例演示了deno_url库的主要功能,包括URL解析、构建、修改、相对URL解析、查询参数处理和错误处理等。每个示例都有清晰的注释说明其功能。

deno_url是Rust生态中处理URL的一个强大选择,特别适合需要严格遵循标准和高性能的场景。

回到顶部