【node】深入探讨 class URL

news2024/10/9 22:17:08

【node】深入探讨 class URL

📌 浅说 fileURLToPath()

vite.config.ts中有这么一段代码:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
export default defineConfig({
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

咱们先来讲讲 fileURLToPath:

// * @param url The file URL string or URL object to convert to a path.
url:url要转换为路径的文件url字符串或url对象。

// * @default undefined
options: 如果' path '应该作为Windows文件路径返回,则为' true ',如果为posix则为' false ',如果为系统默认值则为' undefined '// * @return The fully-resolved platform-specific Node.js file path.
返回:特定平台完全解析的Node.js文件路径。

以下示例,来加深理解:

import { fileURLToPath } from 'node:url'

import.meta.url
// file:///D:/test-project/vite.config.ts

fileURLToPath(import.meta.url)
// D:\test-project\vite.config.tsnew URL('file:///C:/path/').pathname
// Incorrect: /C:/path/

✔️ fileURLToPath('file:///C:/path/')
// Correct:   C:\path\ (Windows)new URL('file://nas/foo.txt').pathname
// Incorrect: /foo.txt

✔️ fileURLToPath('file://nas/foo.txt')
// Correct:   \\nas\foo.txt (Windows)new URL('file:///你好.txt').pathname
// Incorrect: /%E4%BD%A0%E5%A5%BD.txt

✔️ fileURLToPath('file:///你好.txt')
// Correct:   /你好.txt (POSIX)new URL('file:///hello world').pathname
// Incorrect: /hello%20world

✔️ fileURLToPath('file:///hello world')
// Correct:   /hello world (POSIX)

回到 vite.config.ts 代码段, 来看看这句代码的输出内容是什么:

fileURLToPath(new URL('./src', import.meta.url))
// console
D:\test-project\src

没错,这个输出结果和模块作用域(__filename/_dirname)相似,如:

  • __filename
__filename
// console
D:\test-project\vite.config.ts
  • __dirname
__dirname
// console
D:\test-project
  • path.dirname(__filename)
path.dirname(\_\_filename)
// console
D:\test-project

那么这段代码的含义,就是使用文件系统路径进行别名化处理

alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
}

比如,有这么一个文件目录树

test-project/
├── src/
│   ├── assets/
│   │   └── logo.svg
│   └── App.vue
├── index.html
├── vite.config.ts
└── package.json

App.vue 中有这么一段代码,来阐述文件路径别名的实际应用:

<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

当然,alias 并不局限对象来实现文件路径别名。它可以是一个 对象,或一个 数组,类型如下:

Record<string, string> |
  Array<{
    find: string | RegExp
    replacement: string
    customResolver?: ResolverFunction | ResolverObject
  }>

🔍 探讨 new URL()new URL() 区别

回到正题,探讨 new URL()

既然有 Web API 的 new URL() ,那么 nodejs 为什么又重写呢?

  • import { URL } from 'node:url' 中的 URL 是 Node.js 提供的内置模块 url 中的类,用于处理 URL。

  • 而 MDN 的 URL API 是指 Web 标准中定义的用于处理 URL 的 JavaScript API。

这两者虽然都是用于处理 URL,但有一些区别:

  1. Node.js URL 模块:Node.js 的 url 模块提供了一组用于解析和格式化 URL 的实用工具。它主要用于服务器端的 JavaScript 程序,如在 HTTP 请求中解析 URL,或在文件系统中处理文件路径。它与浏览器的 URL API 在一些细节上有所不同,因为 Node.js 和浏览器在处理 URL 和文件路径时有不同的需求。

  2. MDN URL API:MDN 上的 URL API 是 Web 标准中定义的 JavaScript API,用于在浏览器环境中处理 URL。它提供了一组用于创建、解析和操作 URL 的方法和属性。与 Node.js 的 URL 模块相比,它更适用于在客户端 JavaScript 中操作 URL,如在 Web 应用程序中处理页面的 URL。

虽然这两者有不同的实现和使用场景,但它们都是用于处理 URL 的工具。如果你在 Node.js 环境下开发,可以使用 node:url 模块中的 URL 类。如果你在浏览器环境下开发,可以使用浏览器原生的 URL API。

方法使用、输出区别

  1. node
// vite.config
import { URL } from 'node:url'
new URL(import.meta.url)

// terminal
URL {
  href: 'file:///D:/test-project/vite.config.ts',
  origin: 'null',
  protocol: 'file:',
  username: '',
  password: '',
  host: '',
  hostname: '',
  port: '',
  pathname: '/D:/test-project/vite.config.ts',
  search: '',
  searchParams: URLSearchParams {},
  hash: ''
}
  1. WEB API
// App.vue
new URL(import.meta.url)

// Browser console
URL {
  hash: "",
  host: "localhost:5173",
  hostname: "localhost",
  href: "http://localhost:5173/src/App.vue",
  origin: "http://localhost:5173",
  password: "",
  pathname: "/src/App.vue",
  port: "5173",
  protocol: "http:",
  search: "",
  searchParams: URLSearchParams {size: 0},
  username: "",
}

本质区别就是 web api: URL 无需引用便可用,它是浏览器中的一个标准,当然由浏览器去解析。

如果浏览器尚不支持URL()构造函数,则可以使用Window中的Window.URL属性。

但是如果你这么做:

// browser
console.log(new URL(import.meta.url))

// console
Uncaught SyntaxError: Cannot use 'import.meta' outside a module

原因是,浏览器终端无法处理 import.meta, 它由 JavaScript 运行时(即浏览器Node.js)负责处理,然后交给浏览器呈现。

当然,你可以这么做:

// Browser console
console.log(new URL('file:///D:/test-project/vite.config.ts'))

// console
URL {
  hash:"",
  host:"",
  hostname:"",
  href:"file:///D:/test-project/vite.config.ts",
  origin:"file://",
  password:"",
  pathname:"/D:/test-project/vite.config.ts",
  port:"",
  protocol:"file:",
  search:"",
  searchParams: URLSearchParams { size:0 },
  username:""
}

来一个横向比较图示:

在这里插入图片描述
(pc端看效果更佳)

🔐 剖析 Node class URL

参照标准:URL Standard

让我们来看看nodejsURL类的基本结构是怎么写样的:

class URL {
  static createObjectURL(blob: NodeBlob): string
  static revokeObjectURL(id: string): void
  static canParse(input: string, base?: string): boolean
  constructor(input: string | { toString: () => string }, base?: string | URL)
  hash: string
  host: string
  hostname: string
  href: string
  readonly origin: string
  password: string
  pathname: string
  port: string
  protocol: string
  search: string
  readonly searchParams: URLSearchParams
  username: string
  toString(): string
  toJSON(): string
}

方法:

  1. createObjectURL(blob)

    • 用途:创建一个指向传入的 Blob 对象的 URL。
    • 注意事项:需要注意在使用后需要通过 revokeObjectURL(id) 来释放 URL,防止内存泄漏。
    • 示例
      const { URL } = require('url')
      const url = new URL('https://example.com')
      const blob = new Blob(['Hello, world!'], { type: 'text/plain' })
      const objUrl = url.createObjectURL(blob)
      console.log(objUrl) // 输出类似 'blob:https://example.com/5a3c5ebc-79f9-4a70-a3ec-6d9f8a2f2c5f'
      url.revokeObjectURL(objUrl) // 使用后需要撤销 URL
      
  2. revokeObjectURL(id)

    • 用途:释放之前通过 createObjectURL 创建的 URL。
    • 注意事项:调用后,之前通过 createObjectURL 创建的 URL 将不再有效,应及时释放以避免内存泄漏。
    • 示例:见上面的示例。
  3. canParse(input, base)

    • 用途:检查给定的字符串是否能被解析为有效的 URL。
    • 注意事项:返回一个布尔值,用于判断是否能够成功解析。
    • 示例
      const { URL } = require('url')
      console.log(URL.canParse('https://example.com')) // true
      console.log(URL.canParse('not_a_url')) // false
      

属性:

  1. hash

    • 用途:获取或设置 URL 的片段标识符(即 # 后面的内容)。
    • 注意事项:可以直接读取和修改,修改后 URL 对象的其他部分会相应更新。
    • 示例
      const { URL } = require('url')
      const url = new URL('https://example.com#section')
      console.log(url.hash) // 输出 '#section'
      url.hash = '#newsection'
      console.log(url.href) // 输出 'https://example.com#newsection'
      
  2. host / hostname / href / origin / password / pathname / port / protocol / search / username

    • 用途:分别获取或设置 URL 的主机、主机名、完整 URL、源、用户名、路径名、端口、协议、查询部分。
    • 注意事项:这些属性用于精确控制和操作 URL 的不同部分,修改后 URL 对象的其他部分会相应更新。
    • 示例
      const { URL } = require('url')
      const url = new URL('https://username:password@example.com:8080/path?query=string#fragment')
      console.log(url.host) // 输出 'example.com:8080'
      console.log(url.pathname) // 输出 '/path'
      url.protocol = 'https:'
      url.searchParams.set('newparam', 'value')
      console.log(url.href) // 输出 'https://username:password@example.com:8080/path?query=string&newparam=value#fragment'
      
  3. searchParams

    • 用途:获取 URL 查询参数部分的 URLSearchParams 对象,用于操作和管理 URL 的查询参数。
    • 注意事项:可以使用 set()get()append()delete() 等方法来修改查询参数,修改后 URL 对象的 href 属性会相应更新。
    • 示例
      const { URL } = require('url')
      const url = new URL('https://example.com/path?query=string')
      url.searchParams.set('newparam', 'value')
      console.log(url.href) // 输出 'https://example.com/path?query=string&newparam=value'
      

其他方法:

  • toString():返回序列化后的完整 URL 字符串。
  • toJSON():返回 URL 对象的 JSON 表示,通常与 JSON.stringify() 结合使用。

实际应用场景:

这些方法和属性使得 URL 类在 Node.js 中成为处理和操作 URL 非常便捷的工具,特别适用于需要频繁处理 URL 的场景,如 Web 服务器开发爬虫程序等。

⛳ 总结

当谈论现代 Web 开发时,涉及到多种 URL 相关的概念和工具。

Node.js 中的 URL 类提供了强大的 URL 解析和操作功能,适用于服务器端和脚本任务。例如,它允许开发者轻松解析和修改 URL 的各个部分,如协议、主机名、路径和查询参数。

与此同时,Vite 提供了 fileURLToPath 函数,用于将文件 URL 转换为本地文件路径,便于在开发过程中处理模块和资源。

此外,Vite 还支持使用 alias 别名,使开发者能够通过自定义简短的名称引用复杂或深层次的文件路径,提高了项目结构的清晰度和开发效率。

尽管 Node.js 的 URL 类提供了广泛的 URL 处理功能,但它与 Web API 中的 URL 对象存在一些本质区别。

Node.js 的 URL 类主要用于服务器端编程和脚本任务,它的实现更加偏向于文件系统和模块加载的处理。

而 Web API 中的 URL 对象则更加面向浏览器环境,提供了对当前页面 URL 的访问和修改,以及处理跨域资源共享(CORS)等网络相关的特性。

因此,开发者在使用这两种 URL 类时,需要根据具体的应用场景和需求选择合适的工具来操作和管理 URL。


【Vinca】 欢迎 点赞、关注、收藏,您的支持将是我分享更多资源的动力哦~
🌸

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1863155.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python学习笔记四

1.自己平方本身 x2 x**4#xx**4 print(x) 2.把一个多位数拆分成单个数&#xff0c;方法一通过字符串下标获取对应元素&#xff0c;并对获取的元素使用eval函数把左右引号去掉&#xff0c;是字符串变为整型&#xff1b;方法二&#xff0c;通过对数进行取余和整除得到各个位的数 …

RK3568平台开发系列讲解(I2C篇)利用逻辑分析仪进行I2C总线的全面分析

🚀返回专栏总目录 文章目录 1. 基础协议1.1. 协议简介1.2. 物理信号1.3. 总线连接沉淀、分享、成长,让自己和他人都能有所收获!😄 1. 基础协议 1.1. 协议简介 IIC-BUS(Inter-IntegratedCircuit Bus)最早是由PHilip半导体(现在被NXP收购)于1982年开发。 主要是用来方…

安卓应用开发学习:获取导航卫星信息

一、引言 我昨天写了《安卓应用开发学习&#xff1a;获取经纬度及地理位置描述信息》日志&#xff0c;今天再接再厉&#xff0c;记录一下跟着《Android App 开发进阶与项目实战》一书&#xff0c;实现获取导航卫星信息&#xff0c;并在手机上显示的功能的情况。先上实现后的在…

go语言day2 配置

使用cmd 中的 go install &#xff1b; go build 命令出现 go cannot find main module 错误怎么解决&#xff1f; go学习-问题记录(开发环境)go: cannot find main module&#xff1b; see ‘go help modules‘_go: no flags specified (see go help mod edit)-CSDN博客 在本…

FPGA学习笔记(6)——硬件调试与网表添加探针

对信号进行分析&#xff0c;除了使用内置的ILA IP核&#xff0c;还可以在网表中添加探针。 本节采用之前配置的LED灯闪烁代码&#xff0c;对原始工程进行修改。 如果是新建工程&#xff0c;需要现将代码进行综合Synthesis&#xff0c;然后再进行接下来的操作。 1、点击Open S…

链表数组遍历输出的辨析(二者都含指针的情况下)----PTA期末复习题

输入输出三位学生的学号和信息 一开始我认为是指针&#xff0c;直接背了指针输出的方式&#xff1b;p;p!NULL;pp->next 这个是错误的 下面这个输出是正确的方式 分析怎么区分这两个 举个例子来 数组遍历&#xff1a; 链表遍历&#xff1a; 输出的结果&#xff1a; 如果将…

浏览器扩展V3开发系列之 chrome.cookies 的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.cookies API能够让我们在扩展程序中去操作浏览器的cookies。 在使用 chrome.cookies 要先声明…

【Redis】Zset有序集合常用命令以及使用场景

Redis 的有序集合&#xff08;Sorted Set&#xff0c;简称 Zset&#xff09;是一个非常强大的数据结构&#xff0c;它结合了集合&#xff08;Set&#xff09;的唯一性和列表&#xff08;List&#xff09;的有序性。每个元素都关联一个评分&#xff08;score&#xff09;&#x…

减少液氮罐内液氮损耗的方法

监测与管理液氮容器的密封性能 液氮容器的密封性能直接影响液氮的损耗情况。一个常见的损耗源是容器本身的密封不良或老化导致的泄漏。为了有效减少液氮损耗&#xff0c;首先应当定期检查液氮容器的密封性能。这可以通过简单的方法如肉眼检查外观&#xff0c;或者更精确的方法…

SEO与AI的结合:如何用ChatGPT生成符合搜索引擎优化的内容

在当今数字时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为每个网站和内容创作者都必须掌握的一项技能。SEO的主要目标是通过优化内容&#xff0c;使其在搜索引擎结果页面&#xff08;SERP&#xff09;中排名更高&#xff0c;从而吸引更多的流量。然而&#xf…

嵌入式学习——硬件(ARM体系架构)——day51

1. S3C2440基础知识——一条指令四个字节 1.1 定义 S3C2440 是三星&#xff08;Samsung&#xff09;公司设计的一款基于 ARM920T 核心的微处理器&#xff0c;广泛应用于嵌入式系统中&#xff0c;属于三星的 S3C24xx 系列。 1.2 处理器核心 ARM920T&#xff1a;基于 ARM v5T …

[C#][opencvsharp]C#使用opencvsharp进行年龄和性别预测支持视频图片检测

使用 OpenCVSharp 来调用 age_net.caffemodel 和 gender_net.caffemodel 来进行性别和年龄预测涉及几个步骤。以下是一个简化的流程和示例文案&#xff1a; 1. 准备工作 确保你已经安装了 OpenCVSharp 和相关的依赖项。确保你有 age_net.prototxt、age_net.caffemodel、gende…

市面上很轻的 100kW 负载组

FX100S-C 负载组 EAK的 FX100S-C 负载组在轻质外壳中以 415Vac 50Hz 提供 100kW 的连续负载。数字仪表允许您测量功率、电压、电流和频率&#xff0c;同时还允许您在进行测试时记录数据。 EAK是市场上最轻的 100kW 负载组之一&#xff0c;它将使您能够访问其他负载组无法到达…

离线部署OpenIM

目录 1.提取相关安装包和镜像 2.安装docker和docker-compose 3.依次导入镜像 4.解压安装包 5.执行安装命令 6.PC Web 验证 7.开放端口 7.1IM 端口 7.2Chat 端口 7.3 PC Web 及管理后台前端资源端口 “如果您在解决类似问题时也遇到了困难&#xff0c;希望我的经验分享…

服务运营 | MS文章精选:线上点单,当真免排队?餐饮零售与医疗场景中的全渠道运营

编者按&#xff1a; 小A走进了一家奶茶店&#xff0c;准备向店员点单&#xff0c;但却在屏幕上看到还有98杯奶茶待制作&#xff08;因为线上订单突然暴增&#xff09;。因此&#xff0c;小A不满地嘟囔着离开了奶茶店。这个例子展示了线上渠道可能会对线下渠道造成一些负面影响…

并发编程-04synchronized原理

并发编程-04synchronized原理 一 synchronized基础 1.1 并发安全问题 在学习synchronized原理之前&#xff0c;我们先要了解synchronized是干嘛用的&#xff0c;什么场景下需要使用它&#xff0c;以及它的使用方式有哪些&#xff1f;接下来我们去根据一个业务场景去了解下sy…

【排序 队列】1585. 检查字符串是否可以通过排序子字符串得到另一个字符串

本文涉及知识点 排序 队列 LeetCode1585. 检查字符串是否可以通过排序子字符串得到另一个字符串 给你两个字符串 s 和 t &#xff0c;请你通过若干次以下操作将字符串 s 转化成字符串 t &#xff1a; 选择 s 中一个 非空 子字符串并将它包含的字符就地 升序 排序。 比方说&a…

密码学:用随机函数隐藏指纹

英文中e的出现频率高&#xff0c;加密后&#xff0c;频率最高的那个符号代表e。这是历史上的一次真实案例。这些符号的概率&#xff0c;叫做“指纹”。 把e加密成2个符号&#xff0c;用随机函数选择&#xff0c;例如70%概率下选择符号1&#xff0c;30%选择符号2。解密时&#…

Pythonnet能导入clr,但无法引入System模块?

【pythonnet详解】—— Python 和 .NET 互操作的库_pythonnet 详细使用-CSDN博客 Python中动态调用C#的dll动态链接库中方法_python 如何调用c# dll-CSDN博客 需求&#xff1a;Python调用并传List<float>类型参数给.Net 起初&#xff1a;直接 # 创建一个Python浮点数…

数字逻辑--课程设计报告

##智力竞赛抢答器设计 如果对这个有兴趣或者需要电路图或者报告的话请私聊我