【node】深入探讨 class URL

【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.mfbz.cn/a/744761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

github无法访问,下载慢的解决方法

GitHub是一个存储分享无数的开源项目和代码的宝库网站。然而&#xff0c;由于一些原因&#xff0c;国内用户在访问GitHub时常常遭遇无法访问或下载速度缓慢的问题。这不仅影响了开发者的工作效率&#xff0c;也使一些想要访问下载github文件的普通用户遇到困难。下面小编就来和…

线性代数、矩阵计算

一、线性代数 1、对于向量&#xff0c;若a是标量&#xff0c;为a的绝对值乘以b的向量长度。 2、点乘 3、范数&#xff1a;向量或者矩阵的长度 L1范数&#xff1a;&#xff08;对向量&#xff09;每个元素的绝对值求和 L2范数&#xff1a;&#xff08;对向量&#xff09;torch.…

Websocket在Java中的实践——最小可行案例

WebSocket是一种先进的网络通信协议&#xff0c;它允许在单个TCP连接上进行全双工通信&#xff0c;即数据可以在同一时间双向流动。WebSocket由IETF标准化为RFC 6455&#xff0c;并且已被W3C定义为JavaScript API的标准&#xff0c;成为现代浏览器的重要特性之一。 WebSocket的…

【嵌入式Linux】i.MX6ULL 外部中断服务函数的初始化

文章目录 1. Cortex-A7 中断系统1.1 分析1.2 具体处理流程 2. 外部中断服务函数的初始化2.1 基本流程分析2.2 具体代码分析2.2.1. 定义中断处理类型和结构体2.2.2. 初始化中断系统2.2.3. 注册中断处理函数2.2.4. 具体的中断处理逻辑2.2.5. 默认的中断处理函数 3. 完整代码 本文…

002_unsigned long数据比较的坑?

【背景】 unsigned long 类似数据的比较问题&#xff0c;先上一段代码&#xff0c;如下图所示&#xff1a; 就是图中框出的部分&#xff0c;眨眼一看&#xff0c;应该没啥问题&#xff0c;而且我也在本地的编译器vs2019上编译了&#xff0c;确实也没有报错&#xff0c;所以就修…

【Linux】静态库、动态库

动静态库里面包含的是源文件通过汇编阶段生成的后缀为.o的可重定位目标文件。我们在使用C语言&#xff0c;包含一个stdio.h头文件就可以使用scanf方法&#xff0c;其实都是系统调用了相应的头文件和库&#xff0c;库里面有开发者已经写好各种方法。也就是说我们在使用C语言时&a…

Java | Leetcode Java题解之第191题位1的个数

题目&#xff1a; 题解&#xff1a; public class Solution {public int hammingWeight(int n) {int ret 0;while (n ! 0) {n & n - 1;ret;}return ret;} }

【学习】软件测试中常见的文档类型及其作用

在软件开发的生命周期中&#xff0c;软件测试是确保产品质量的关键步骤。为了系统地进行测试活动&#xff0c;并保证测试结果的有效性和可追溯性&#xff0c;产生了一系列标准化的测试文档。这些文档不仅为测试人员提供了执行指南&#xff0c;而且为项目管理者和利益相关者提供…

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

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

Discourse 的 AI 内容分享

虽然 Discourse 的 AI 接口调用是需要比较高的用户权限或者管理员权限。 但是对已经生成的结果&#xff0c;Discourse 是可以保存并且分享的。 例如&#xff0c;我们搜索了一些美食的做法。 在页面的下面有一个分享 AI 对话的按钮。 在随后弹出的界面中&#xff0c;会又一个…

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

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

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

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

第十次作业

1.登陆界面 2.导航页面 3.接口&#xff08;我负责的主要是管理员管理用户和密码的界面&#xff09; import request from /utils/request// 登录 export function login(data) {return request({url: /user/login,method: post,data}) }// 获取用户信息 export function getIn…

网关登录校验

如何在网关转发之前做登录校验&#xff1f; 网关请求处理流程 如何在网关转发之前做登录校验&#xff1f; 网关如何将用户信息传递给微服务&#xff1f; 如何在微服务之间传递用户信息&#xff1f; 自定义过滤器 网关过滤器有两种&#xff0c;分别是&#xff1a; GatewayFi…

春秋云境:CVE-2022-25411[漏洞复现]

根据题目提示和CNNVD优先寻找后台管理地址 靶机启动后&#xff0c;使用AWVS进行扫描查看网站结构 在这里可以看到后台管理的登录地址&#xff1a;/admin/&#xff0c;根据题目提示可知是弱口令 尝试admin、123456、admin666、admin123、admin888...等等常见弱口令 正确的账户…

论文导读 | Manufacturing Service Operations Management近期文章精选

编者按 在本系列文章中&#xff0c;我们梳理了顶刊Manufacturing & Service Operations Management5月份发布有关OR/OM以及相关应用的文章之基本信息&#xff0c;旨在帮助读者快速洞察行业/学界最新动态。 推荐文章1 ● 题目&#xff1a;Robust Drone Delivery with Weath…

KVM网络模式设置

一、KVM网络模式介绍 1、NAT ( 默认上网 ) 虚拟机利用host机器的ip进行上网,对外显示一个ip;virbr0是KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供NAT访问外网的功能,默认ip为192.168.122.1 2、自带的Bridge 将虚拟机桥接到host机器的网卡上,vm和ho…

【C++题解】1712. 输出满足条件的整数2

问题&#xff1a;1712. 输出满足条件的整数2 类型&#xff1a;简单循环 题目描述&#xff1a; 有这样的三位数&#xff0c;其百位、十位、个位的数字之和为偶数&#xff0c;且百位大于十位&#xff0c;十位大于个位&#xff0c;请输出满所有满足条件的整数。 输入&#xff1…

C++ | Leetcode C++题解之第191题位1的个数

题目&#xff1a; 题解&#xff1a; class Solution { public:int hammingWeight(uint32_t n) {int ret 0;while (n) {n & n - 1;ret;}return ret;} };

SpringBoot控制反转和依赖注入

目录 一、内聚和耦合 二、分层解耦 三、具体实现 四、bean的组件扫描 五、bean注入 一、内聚和耦合 在了解分层解耦的概念之前我们我们要去先了解一下内聚和耦合。内聚&#xff1a;通常将的是软件中各个模块之间的功能联系。耦合衡量软件各个模块之间的依赖、关联的程度。一…
最新文章