# normalize-url 中文文档

规范地址：https://npmcn.com/package/normalize-url/

版本：10\.0\.0
npm 元数据更新时间：2026-10-14T17:25:32.994Z
中文译文更新时间：2026-11-05T16:31:20.480Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/normalize-url
原文对照：https://npmcn.com/package/normalize-url/?lang=original
项目主页：https://github.com/sindresorhus/normalize-url#readme
源码仓库：https://github.com/sindresorhus/normalize-url

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：72.5 kB，5 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- 首次发布：2015-01-11T14:26:12.438Z
- 最新版本发布：2026-10-14T17:25:32.695Z
- 近 30 天下载量：190772691（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：58（近 12 个月 4 个）

## 中文简介

将 URL 正常化

## 安装

```sh
npm install normalize-url
```

也可以使用：`pnpm add normalize-url`、`yarn add normalize-url`、`bun add normalize-url`

## README

# 正常运行 [![Coverage Status](https://codecov.io/gh/sindresorhus/normalize-url/branch/main/graph/badge.svg)](https://codecov.io/gh/sindresorhus/normalize-url)

> [规范化](https://en.wikipedia.org/wiki/URL_normalization) 一个 URL

当您需要显示、存储、去重复、排序、比较等, URL 时有用 .

> \[注\] 这个软件包是 **没有** 进行 URL 消毒. [垃圾进来,垃圾出去.](https://en.wikipedia.org/wiki/Garbage_in,_garbage_out) 如果您在服务器上下文中使用了这个并接受URL作为用户输入,则由您来防范无效的URL, [径向攻击](https://owasp.org/www-community/attacks/Path_Traversal)等 (中文(简体) ).

## 安装

```sh
npm install normalize-url
```

## 使用量

```js
import normalizeUrl from 'normalize-url';

normalizeUrl('sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('//www.sindresorhus.com:80/../baz?b=bar&a=foo');
//=> 'http://sindresorhus.com/baz?a=foo&b=bar'
```

## API 密码

### 正常Url( url, 选项)

带有自定义协议的 URL 不正常化, 并且只是默认通过 。 支持的协议有: `https`, (中文(简体) ), `http`, (中文(简体) ), `file`,以及 `data`。使用 [`customProtocols`](https://npmcn.com/package/normalize-url/#readme-customprotocols) 选项以添加对补充协议的支持.

具有基本认证的人类友好URL(例如, `user:password@sindresorhus.com`)不处理,因为基本的认证与自定义协议相冲突. [基本认证 URL 也被贬值 .](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#access_using_credentials_in_the_url)

**说明:** 计划,其中有一个点,然后 `//` 是一个自定义的协议,所以它也通过,而URL中没有任何东西是正常的. `example.com/path` 是一个主机并获得 `http:` 准备,但 `example.com://host/path` 是名为 `example.com` 并独自一人。 使用 [`customProtocols`](https://npmcn.com/package/normalize-url/#readme-customprotocols) 选项是故意实现一个正常化.

无论选项如何,一个正常的URL也会得到这些更改:

-   Tab, 车厢返回, 线路种子被从任何地方删除, 就像 URL 解析器所做的那样 。 Whitespace和C0控件从端部被去除,包括U+00A0和一字节顺序标记,它们经常被复制到URL后留下. URL 内的其他白空间被保存, 并逃出一个 URL 解析器 逃脱的地方 .
-   一个 URL 解析协议的小写 。 对于内置协议,它也会将主机小写,将国际化的主机转换为Punycode,解析 `.` 财务报告和审定财务报表 `..` ,并删除默认端口.
-   跟踪点从域主机中删除, 除非更改名称 : `159.189.213..` 留着,因为 `159.189.213` 是 IPv4 地址 `159.189.0.213`。自定义协议的主机不透明,因此其点被保留.
-   路径中的重复斜线被去除,但类似协议的两段除外,例如: `/https://`。 。 。 .
-   越狱的比例为大写(`%2f` → `%2F`),但数据URL的介质类型除外,其中"%-外观"的文本是字面的MIME内容. 无保留字符的出逃(字母、数字、, `-`, (中文(简体) ), `.`, (中文(简体) ), `_`, (中文(简体) ), `~`已解码 ()`%7E` → `~`),除片段外,数据 URL 的介质类型,自定义协议的宿主,以及不从开始的路径 `/`。碎片会继续被编码,所以它们不能成为文本指令。 路径和查询还解码了其他出局,其中字符表示相同的未脱逃,如: `%5B` → `[`. 改变结构的逃逸情况,例如 `%2F`, (中文(简体) ), `%3F`, (中文(简体) ), `%23`,以及 `%26`继续逃跑,所以 `%2F` 财务报告和审定财务报表 `/` 与众不同.
-   查询是写的方式 `URLSearchParams` 写入: 值中的空格是 `+`,键中的空格是 `%20`页:1 `?` 实值 `%3F`,则a `%` 开始,没有逃脱是 `%25`空参数,如 `?a=1&&b=2`,删除。 发生于 `sortQueryParameters: false` 我也一样。 无效的 UTF-8 越狱变为 U+FFFD, 如 `URLSearchParams` 解码,所以 `?q=%E9` 变成 `?q=%EF%BF%BD`,它修改了将查询读取为拉丁-1的服务器的值.
-   数据 URL 获得其 MIME 类型和 `charset` 数值已小写. `text/plain` 当无物跟随它时,它将被移除 `charset=us-ascii` 打开 `text/plain`. 从不需要的参数值中去除引号,从基数64数据端去出白空格.

#### url 密码

类型 : `string`

要正常化的 URL, 包括 [数据 URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)。 。 。 .

#### 选项

类型 : `object`

##### 默认协议

类型 : `string`  
默认 : `'http'`

通常情况下 `'https'` 或者说 `'http'`。跟踪 `:` 已接受。 非计划值, 如 `'https://'`,丢出一个 `TypeError`。 。 。 .

**说明:** 未构建的协议, 例如 `'ftp'`这是最好的。 它创建的 URL 已经正常化, 而与 协议 所写的 URL 则作为自定义协议通过, 除非协议在其中 `customProtocols`。 。 。 .

##### 自定义协议

类型 : `string[]`  
默认 : `undefined`

除内在协议外的正常化协议`https`, (中文(简体) ), `http`, (中文(简体) ), `file`, (中文(简体) ), `data`) (中文(简体) ).

用于类似HTTP的自定义协议,例如Electron计划或app专用协议.

协议应不指定 `:`尽管一个跟随者被接受。 名曰无相.

**说明:** 重写路径的选项( E)`removePath`, (中文(简体) ), `transformPath`, (中文(简体) ), `removeDirectoryIndex`,且路径的 %-解码)只有在路径开始时才适用 `/`时,如 `sindre://host/a/b` 财务报告和审定财务报表 `sindre:/a/b`。一个路径不透明的URL,例如 `sindre:a/b`,没有用于这些选项的片段可用,一个 URL 解析器不会让库更改它,所以它们被默默地忽略了.

**说明:** `transformPath` 财务报告和审定财务报表 `removeDirectoryIndex` 重建其组件中的路径,它不能拼写类似协议的两条斜线,例如 `sindre://host/a/s3://b/index.html`其中一个被丢弃,用于这两个选项,而图书馆则将这两个选项存放在其他地方.

```js
normalizeUrl('sindre://www.sorhus.com', {customProtocols: ['sindre']});
//=> 'sindre://sorhus.com'

normalizeUrl('sindre://www.sorhus.com/foo/', {customProtocols: ['sindre']});
//=> 'sindre://sorhus.com/foo'
```

##### 正式议定书

类型 : `boolean`  
默认 : `true`

预留 `defaultProtocol` 如果它与协议相关,则将其移至 URL.

与 `false`,一个协议相对的 URL 仍然与协议相对,即使与 `defaultProtocol` 或者说 `forceHttps` 设置.

```js
normalizeUrl('//sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('//sindresorhus.com', {normalizeProtocol: false});
//=> '//sindresorhus.com'
```

##### 强制Http

类型 : `boolean`  
默认 : `false`

将HTTPS规范化为HTTP.

**说明:** 更改方案会放弃旧方案默认的端口, 所以 `forceHttp` 转弯 `https://example.com:443` 输入 `http://example.com` 财务报告和审定财务报表 `forceHttps` 转弯 `http://example.com:80` 输入 `https://example.com`。保留了两个方案都不是默认的端口.

```js
normalizeUrl('https://sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com', {forceHttp: true});
//=> 'http://sindresorhus.com'
```

##### 强度

类型 : `boolean`  
默认 : `false`

将 HTTP 规范为 HTTPS .

**说明:** 更改方案会放弃旧方案默认的端口, 所以 `forceHttp` 转弯 `https://example.com:443` 输入 `http://example.com` 财务报告和审定财务报表 `forceHttps` 转弯 `http://example.com:80` 输入 `https://example.com`。保留了两个方案都不是默认的端口.

```js
normalizeUrl('http://sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('http://sindresorhus.com', {forceHttps: true});
//=> 'https://sindresorhus.com'
```

无法使用此选项 `forceHttp` 选项.

##### 条形认证

类型 : `boolean`  
默认 : `true`

脱去 [认证](https://en.wikipedia.org/wiki/Basic_access_authentication) uRL的一部分.

```js
normalizeUrl('https://user:password@sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://user:password@sindresorhus.com', {stripAuthentication: false});
//=> 'https://user:password@sindresorhus.com'
```

##### 脱发

类型 : `boolean`  
默认 : `false`

剥去 URL 的散列部分 .

```js
normalizeUrl('sindresorhus.com/about.html#contact');
//=> 'http://sindresorhus.com/about.html#contact'

normalizeUrl('sindresorhus.com/about.html#contact', {stripHash: true});
//=> 'http://sindresorhus.com/about.html'
```

##### 条状协议

类型 : `boolean`  
默认 : `false`

从 URL 中删除协议 : `http://sindresorhus.com` → `sindresorhus.com`。 。 。 .

它可以删除一个 `https://`,一个 `http://` 或线索 `//` 从协议相对的 URL, 而不是其他.

**说明:** 结果不是一个完整的URL,所以再次使其正常化可以改变它:一个被移除的协议所保存的端口是下一个被准备的协议的默认之一.

```js
normalizeUrl('https://sindresorhus.com');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com', {stripProtocol: true});
//=> 'sindresorhus.com'
```

##### 条纹碎片

类型 : `boolean`  
默认 : `true`

脱去 [文本块](https://web.dev/text-fragments/) uRL的一部分.

**说明:** 如果 `stripHash` 选项设定为 `true`,因为散列包含文本碎片.

```js
normalizeUrl('http://sindresorhus.com/about.html#:~:text=hello');
//=> 'http://sindresorhus.com/about.html'

normalizeUrl('http://sindresorhus.com/about.html#section:~:text=hello');
//=> 'http://sindresorhus.com/about.html#section'

normalizeUrl('http://sindresorhus.com/about.html#:~:text=hello', {stripTextFragment: false});
//=> 'http://sindresorhus.com/about.html#:~:text=hello'

normalizeUrl('http://sindresorhus.com/about.html#section:~:text=hello', {stripTextFragment: false});
//=> 'http://sindresorhus.com/about.html#section:~:text=hello'
```

##### 脱衣舞

类型 : `boolean`  
默认 : `true`

删除 `www.` 从 URL 中.

**说明:** A 类 `www.` 之后没有合适的域被留下,所以 `www.com` 财务报告和审定财务报表 `www.a.b` 未更改.

```js
normalizeUrl('http://www.sindresorhus.com');
//=> 'http://sindresorhus.com'

normalizeUrl('http://www.sindresorhus.com', {stripWWW: false});
//=> 'http://www.sindresorhus.com'
```

##### 删除查询参数

类型 : `Array<RegExp | string> | boolean`  
默认 : `[/^utm_\w+/i]`

删除匹配所提供字符串或正则x的查询参数 。 匹配与 %-decode 密钥, 方式 `URLSearchParams` 读到一个,所以 `+` 是一个空间,并且 `%2F` 是斜线: 写 `a/b` 而不是说 `a%2Fb`。 。 。 .

全球和粘稠的Regex旗被剥去.

```js
normalizeUrl('www.sindresorhus.com?foo=bar&ref=test_ref', {
    removeQueryParameters: ['ref']
});
//=> 'http://sindresorhus.com/?foo=bar'
```

如果提供了布尔, `true` 将删除所有查询参数.

```js
normalizeUrl('www.sindresorhus.com?foo=bar', {
    removeQueryParameters: true
});
//=> 'http://sindresorhus.com'
```

`false` 将不删除任何查询参数.

```js
normalizeUrl('www.sindresorhus.com?foo=bar&utm_medium=test&ref=test_ref', {
    removeQueryParameters: false
});
//=> 'http://sindresorhus.com/?foo=bar&ref=test_ref&utm_medium=test'
```

##### 保留查询参数

类型 : `Array<RegExp | string>`  
默认 : `undefined`

只保留匹配任何提供的字符串或正则x的查询参数 。 匹配对象为 %-decode 密钥, 与 `removeQueryParameters`。一个空阵列与什么也没有匹配,所以它删除了每个参数,与 `true` 联 合 国 `removeQueryParameters`。 。 。 .

**说明:** 它会超越 `removeQueryParameters` 选项.

全球和粘稠的Regex旗被剥去.

```js
normalizeUrl('https://sindresorhus.com?foo=bar&ref=unicorn', {
    keepQueryParameters: ['ref']
});
//=> 'https://sindresorhus.com/?ref=unicorn'
```

##### 删除拖线

类型 : `boolean`  
默认 : `true`

删除后面的斜线 .

**说明:** 单曲 `/` 根路径也被去除,除非 `removeSingleSlash` 选项设定为 `false` **财务报告和审定财务报表** 输入书写了斜线本身.

**说明:** `removeSingleSlash: false` 读取输入时的后端斜线, 因此属于点段的斜线解析器仍然计数 . `https://example.com/a/../` 财务报告和审定财务报表 `https://example.com/a/..` 是同一个URL,但只有第一个保留了根切.

```js
normalizeUrl('http://sindresorhus.com/redirect/');
//=> 'http://sindresorhus.com/redirect'

normalizeUrl('http://sindresorhus.com/redirect/', {removeTrailingSlash: false});
//=> 'http://sindresorhus.com/redirect/'

normalizeUrl('http://sindresorhus.com/', {removeTrailingSlash: false});
//=> 'http://sindresorhus.com'
```

##### 删除单斜线

类型 : `boolean`  
默认 : `true`

删除脚本 `/` 输出中的路径名。 此选项独立于 `removeTrailingSlash`。 。 。 .

这个 `/` 当查询或散列跟随它时,例如 `https://sindresorhus.com/?a=1`。 。 。 .

```js
normalizeUrl('https://sindresorhus.com/');
//=> 'https://sindresorhus.com'

normalizeUrl('https://sindresorhus.com/', {removeSingleSlash: false});
//=> 'https://sindresorhus.com/'
```

##### 删除目录Index

类型 : `boolean | Array<RegExp | string>`  
默认 : `false`

从匹配任何提供字符串或正则ex的路径中删除默认目录索引文件。 匹配对象为 %- 解码组件, 与 `transformPath` 被赋予,所以 `index.html` 匹配拼入的路径 `index%2Ehtml`它运行于之后 `transformPath`,因此它也会去除函数在结尾留下的索引文件.

何时 `true`缩写 `/^index\.[a-z]+$/` 已使用.

**说明:** 删除索引后留下了一条线索的斜线, 不管输入是否写了一条, 所以 `http://example.com/foo/index.html` 变成 `http://example.com/foo/` 接下来 `http://example.com/foo`编辑 `removeTrailingSlash` 选项决定斜线是否保留.

全球和粘稠的Regex旗被剥去.

```js
normalizeUrl('www.sindresorhus.com/foo/default.php', {
    removeDirectoryIndex: [/^default\.[a-z]+$/]
});
//=> 'http://sindresorhus.com/foo'
```

##### 删除外部端口

类型 : `boolean`  
默认 : `false`

从 URL 中删除一个明确的端口号.

端口443总是从HTTPS URL中去除,80总是从HTTP URL中去除,不管这个选项如何.

```js
normalizeUrl('sindresorhus.com:123', {
    removeExplicitPort: true
});
//=> 'http://sindresorhus.com'
```

##### 排序查询参数

类型 : `boolean`  
默认 : `true`

按密钥排序查询参数,按代码单位顺序排列,因此小写前的大写字母排序,字母前为数字。 共享密钥的参数保持其被写入的顺序 .

**说明:** 选项只更改顺序 。 查询以同样的方式书写(参见 [`normalizeUrl`](https://npmcn.com/package/normalize-url/#readme-normalizeurlurl-options)) (中文(简体) ).

```js
normalizeUrl('www.sindresorhus.com?b=two&a=one&c=three', {
    sortQueryParameters: false
});
//=> 'http://sindresorhus.com/?b=two&a=one&c=three'
```

##### 空查询

类型 : `string`  
默认 : `'preserve'`  
数值 : `'preserve' | 'always' | 'never'`

控制空值的查询参数格式化.

-   `'preserve'` - 保留原始格式(`?key` 留下来 `?key`, (中文(简体) ), `?key=` 留下来 `?key=`) (中文(简体) ). 如果同一密钥同时出现两种格式(`?a&a=`),所有实例都将使用格式,而不使用 `=`。 。 。 .
-   `'always'` - 总是包括 `=` 空值( e)`?key` 变成 `?key=`(中文(简体) )
-   `'never'` - 从不包含 `=` 空值( e)`?key=` 变成 `?key`(中文(简体) )

```js
normalizeUrl('www.sindresorhus.com?a&b=', {emptyQueryValue: 'always'});
//=> 'http://sindresorhus.com/?a=&b='

normalizeUrl('www.sindresorhus.com?a&b=', {emptyQueryValue: 'never'});
//=> 'http://sindresorhus.com/?a&b'
```

##### 删除路径

类型 : `boolean`  
默认 : `false`

删除整个 URL 路径, 让主机没有路径 。 查询和散列。 它优先于 `transformPath` 选项.

```js
normalizeUrl('https://example.com/path/to/page', {
    removePath: true
});
//=> 'https://example.com'
```

##### 变换路径

类型 : `Function | false`  
默认 : `false`

自定义转换 URL 路径组件的函数 。 该函数接收了一组非空道组件,并应当返回一个被修改的数组. 归去去去去去来去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去不去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去 组件是 %-decode 的,所以在函数看到它时,一个没有保留的逃出就成为它所代表的字符,一个它返回的字符不再被解码了. 它运行之前 `removeDirectoryIndex`,因此函数仍然看到索引文件,当 `removePath` 已经设定.

```js
// Keep only the first path component
normalizeUrl('https://example.com/api/v1/users', {
    transformPath: (pathComponents) => pathComponents.slice(0, 1)
});
//=> 'https://example.com/api'

// Remove specific components
normalizeUrl('https://example.com/admin/users', {
    transformPath: (pathComponents) => pathComponents.filter(c => c !== 'admin')
});
//=> 'https://example.com/users'
```

## 相关

-   [比较urls](https://github.com/sindresorhus/compare-urls) - 比较 URL ,首先使其正常化

## 常见问题

### normalize-url 是什么？

将 URL 正常化

### 如何安装 normalize-url？

在项目目录运行 npm install normalize-url，或使用 pnpm add / yarn add / bun add。

### normalize-url 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### normalize-url 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### normalize-url 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### normalize-url 可以商用吗？

normalize-url 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### normalize-url 的下载量有多少？

根据 npm 官方下载统计，normalize-url 在 2026/10/05 – 2026/11/03 这 30 天内被下载 190,772,691 次，日均约 6,359,090 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### normalize-url 还在维护吗？

最新版本 10\.0\.0 发布于 2026/10/15（22 天前）；至今共发布 58 个版本，其中过去 12 个月发布了 4 个；首次发布于 2015/01/11。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

