Skip to content
0

node:url

对于路径:https://user:pass@xxx.com:8000/p/a/t/h?q=s#foo

各个部分的命名如下

| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
|` https:` | `//` | `user` | `:` | `pass` | `@` | `xxx.com` | `:` | `8000` | `/p/a/t/h` | `?` | `q=s` | `#foo` |
|  protocol |  | username |  |  password |   | hostname |  | port | pathname |  | query | hash |
|  ||  auth |||  | host  |||  |  search ||  |
| origin ||||||||| path |||  |
| href |||||||||||

URL

在 Nodejs 中可以直接使用 URL 进行实例化,实际上它是从 url 模块中暴露出来的,

import url from 'node:url'
console.log(url.URL === URL)
// true

可以用 new URL 或者 url.parse 来得到一个 URL 实例,他们产生的结果略有不同,各有一些独特的字段

import { url, URL} from 'node:url'; 

new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash') 
/*
URL {
  href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash',
  host: 'sub.example.com:8080',
  hostname: 'sub.example.com',
  search: '?query=string',
  pathname: '/p/a/t/h',
  protocol: 'https:',
  hash: '#hash'
  port: '8080',
  origin: 'https://sub.example.com:8080', // only 
  username: 'user',   // only 
  password: 'pass',   // only 
  searchParams: URLSearchParams { 'query' => 'string' }, // only 
}
*/
url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'); 
/*
Url {
  href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'
  host: 'sub.example.com:8080',
  hostname: 'sub.example.com',
  search: '?query=string',
  pathname: '/p/a/t/h',
  protocol: 'https:',
  hash: '#hash',
  port: '8080',
  slashes: true, // only 
  auth: 'user:pass', // only 
  query: 'query=string', // only 
  path: '/p/a/t/h?query=string', // only 
}
*/

TIP

推荐使用 new URL 而不是 url.parsesearchParams 可以对查询参数进行丰富的操作

URLSearchParams

URLSearchParams 这个构造函数在 NodeJS/Browser 环境都是全局存在的,但不完全一致,比如 .size 属性,NodeJs 支持的比较晚

初始化

带不带 ? 都是等价的,可以直接传入 search 或者 query 字符串

const params = new URLSearchParams('?foo=1')
const params = new URLSearchParams('foo=1')
添加数据

有两个方法可以写入数据:appendsetappend 只会追加数据,而 set 会覆盖全部如果存在的键

params.append('bar', '1')
params.append('bar', '2')
console.log(params.toString()) //=> bar=1&bar=2
params.set('bar', '3')
console.log(params.toString()) //=> bar=3
删除数据

通过 delete 方法来删除数据,delete 会删除全部如果存在的键

params.append('bar', '1')
params.append('foo', '2')
console.log(params.toString()) //=> bar=1&foo=2
params.delete('bar')
console.log(params.toString()) //=> foo=2
获取数据

获取数据的方式就非常丰富了,包括 get/getAll/keys/values/entries,还有方便遍历的 forEach 方法

params.append('bar', '1')
params.append('bar', '2')
console.log(params.get('bar')) //=> 1
console.log(params.getAll('bar')) //=> ['1', '2']

console.log(params.keys()) //=> URLSearchParams Iterator { 'bar', 'bar' }
console.log(params.values()) //=> URLSearchParams Iterator { '1', '2' }
console.log(params.entries())
//=> URLSearchParams Iterator { [ 'bar', '1' ], [ 'bar', '2' ] }
其他方法

方法 has 用于判断键是否存在,sort 用于按照键名排序(很遗憾不支持自定义排序),需要注意的是 append 方法在添加元素的时候就会自动排序,所以 sort 一般用于给 URLSearchParams 初始化的参数排序

const params = new URLSearchParams('foo=2&bar=3')
console.log(params.has('foo'))
console.log(params.toString()) //=> foo=2&bar=3
params.sort()
console.log(params.toString()) //=> bar=3&foo=2

Unicode/ASCII

自带了对域名进行字符的转换的方法

import url from 'node:url';

console.log(url.domainToASCII('español.com'));
// Prints xn--espaol-zwa.com
console.log(url.domainToASCII('中文.com'));
// Prints xn--fiq228c.com
console.log(url.domainToUnicode('xn--espaol-zwa.com'));
// Prints español.com
console.log(url.domainToUnicode('xn--fiq228c.com'));
// Prints 中文.com

FileUrl 🔄 Path

在处理路径的时候,最常用的两个函数

import { fileURLToPath, pathToFileURL } from 'url'
const currentUrl = import.meta.url
console.log(currentUrl)
// file:///path/to/your/project/app.ts
console.log(fileURLToPath(currentUrl))
// /path/to/your/project/app.ts
console.log(pathToFileURL(fileURLToPath(currentUrl)).href)
// file:///path/to/your/project/app.ts

可以用 fileURLToPathESM 中得到 __dirname__filename

import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

Released under the MIT License.