---
title: "encodeURI 和 encodeURIComponent 有什么区别？ - Angryecho"
description: "encodeURI 和 encodeURIComponent 都用于对字符串进行百分号编码，但它们面向的对象不同： encodeURI：编码一个完整的 URI，同时尽量保留 URI 的结构符号。 encodeURIComponent：编码 URI 中的一个组成部分，例如查询参数的值。"
canonical_url: "https://www.angryecho.com/c/qian_duan_she_qu/p/P2TBC14jbXSmIlt3EqFNf"
meta:
  "og:description": "encodeURI 和 encodeURIComponent 都用于对字符串进行百分号编码，但它们面向的对象不同： encodeURI：编码一个完整的 URI，同时尽量保留 URI 的结构符号。 encodeURIComponent：编码 URI 中的一个组成部分，例如查询参数的值。"
  "og:image": "https://www.angryecho.com/_og/d/c_Post%2Ctitle_~5ZCQ5qe9572R%2Cdescription_~5ZCQ5qe95LiA5LiL77yM5bCx5LiK5ZCQ5qe9572R44CC%2CpostId_P2TBC14jbXSmIlt3EqFNf%2Crevision_~MjAyNi0xMS0wMlQwMjo1NTo1Ni44NjcxNzBa%2Cp_Ii9jL3FpYW5fZHVhbl9zaGVfcXUvcC9QMlRCQzE0amJYU21JbHQzRXFGTmYi%2Cs_w0INToRnaXGzgVSP.png"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "encodeURI 和 encodeURIComponent 有什么区别？"
---

> Index of every page on this site: [llms.txt](https://www.angryecho.com/llms.txt)

# **encodeURI 和 encodeURIComponent 有什么区别？**

`encodeURI` 和 `encodeURIComponent` 都用于对字符串进行百分号编码，但它们面向的对象不同：

- `**encodeURI**`**：编码一个完整的 URI，同时尽量保留 URI 的结构符号。**
- `**encodeURIComponent**`**：编码 URI 中的一个组成部分，例如查询参数的值。**

所以，编码 `https://example.com/a?x=1&y=2` 时，两者结果不同是正常的。

## 一、先看编码结果

```
const url = "https://example.com/a?x=1&y=2";

console.log(encodeURI(url));
// https://example.com/a?x=1&y=2

console.log(encodeURIComponent(url));
// https%3A%2F%2Fexample.com%2Fa%3Fx%3D1%26y%3D2
```

`encodeURI` 编码后，URL 看起来还是一个完整的 URL，这是因为它**保留了 URL 中用于分隔结构的字符**，例如：

```
: / ? & =
```

而 `encodeURIComponent` 会把这些字符也编码掉。结果中的冒号、斜杠、问号、等号和 `&` 都变成了百分号编码。

因此，`encodeURIComponent` 的结果看起来不再像一个可直接使用的 URL。它表示的是“整个 URL 字符串作为一个数据片段”，而不是保留 URL 结构后的地址。

## 二、为什么需要两种方法？

URL 不只是普通字符串，它有自己的结构。例如：

```
https://example.com/search?q=JavaScript&sort=recent
```

可以拆成：

```
协议：       https:
主机名：     example.com
路径：       /search
参数分隔符： ?
参数：       q=JavaScript
参数分隔符： &
参数：       sort=recent
```

在这个结构里，`?`、`&`、`=`、`/` 等字符可能具有特殊含义。如果把它们全部保留或全部编码，结果会完全不同。

`encodeURI` 适合处理**整个 URI**：尽可能保留这些结构符号。

`encodeURIComponent` 适合处理**URI 的某一个值**：将值中的结构符号也编码，避免它们被误认为 URL 的分隔符。

## 三、`encodeURI` 会保留哪些字符？

`encodeURI` 通常会保留 URL 中有结构意义的字符，包括：

```
; , / ? : @ & = + $ # -
```

例如：

```
encodeURI("https://example.com/search?q=hello world");
```

结果：

```
https://example.com/search?q=hello%20world
```

URL 的结构部分仍然保留，而空格被编码成 `%20`。

### `encodeURI` 的一个重要限制

`encodeURI` 会保留 `#`，但 `#` 在 URL 中表示片段标识符。因此，字符串中的 `#` 可能会被浏览器当成 URL 片段的开始。

```
const url = "https://example.com/search#tag";

console.log(encodeURI(url));
// https://example.com/search#tag
```

如果 `#` 本来是某个参数值中的普通字符，就不应该直接依赖 `encodeURI` 来处理整个 URL。应当对参数值单独编码。

## 四、`encodeURIComponent` 会做什么？

`encodeURIComponent` 会编码 URI 中具有结构意义的分隔符，例如：

```
; , / ? : @ & = + $ #
```

例如：

```
const value = "https://example.com/a?x=1&y=2";

console.log(encodeURIComponent(value));
// https%3A%2F%2Fexample.com%2Fa%3Fx%3D1%26y%3D2
```

在这里，整个字符串被作为一个普通值处理。原有的 `https://`、`?` 和 `&` 不再作为 URL 结构符号存在。

## 五、最常见的用法：编码查询参数的值

假设要把用户输入放进查询参数：

```
const keyword = "JavaScript & 前端";

const url = "https://example.com/search?q=" + encodeURIComponent(keyword);

console.log(url);
// https://example.com/search?q=JavaScript%20%26%20%E5%89%8D%E7%AB%AF
```

这里应该使用 `encodeURIComponent`，因为 `keyword` 是参数值。

如果错误地使用 `encodeURI`：

```
const keyword = "JavaScript & sort=recent";

const url = "https://example.com/search?q=" + encodeURI(keyword);
```

`&` 和 `=` 会被保留，拼出来的内容可能被解释成额外的查询参数：

```
https://example.com/search?q=JavaScript%20&%20sort=recent
```

这样就可能改变 URL 的含义。

## 六、简单记忆

可以这样记：

> **处理完整 URL，考虑使用** `**encodeURI**`**；处理 URL 中的某一个值，使用** `**encodeURIComponent**`**。**

示例：

```
const fullUrl = "https://example.com/search?q=hello world";

// 整个 URL
encodeURI(fullUrl);

// 参数值
encodeURIComponent("hello world");
```

不过，实际项目中，拼接查询参数时通常更推荐使用 `URLSearchParams`，避免手动处理编码和分隔符。

## 七、推荐做法：使用 `URLSearchParams`

```
const params = new URLSearchParams({
  q: "JavaScript & 前端",
  sort: "recent",
});

const url = `https://example.com/search?${params.toString()}`;

console.log(url);
// https://example.com/search?q=JavaScript+%26+%E5%89%8D%E7%AB%AF&sort=recent
```

`URLSearchParams` 会处理参数值的编码，并正确构造查询字符串。对于普通的查询参数场景，通常比手动拼接字符串更安全、清晰。

也可以基于 `URL` 对象构造地址：

```
const url = new URL("https://example.com/search");
url.searchParams.set("q", "JavaScript & 前端");
url.searchParams.set("sort", "recent");

console.log(url.toString());
```

## 八、空格编码：`%20` 与 `+`

`encodeURI` 和 `encodeURIComponent` 通常会把空格编码成：

```
%20
```

而 `URLSearchParams` 在序列化查询参数时，可能会把空格表示为：

```
+
```

例如：

```
new URLSearchParams({ q: "hello world" }).toString();
// q=hello+world
```

这两种形式常见于不同的 URL 编码场景。处理查询参数时，优先使用 `URLSearchParams`，不要为了统一格式而随意手动替换。

## 九、几个常见误区

### 1. 不要用 `encodeURIComponent` 编码整个 URL 后直接访问

```
const encoded = encodeURIComponent("https://example.com");
```

结果会变成：

```
https%3A%2F%2Fexample.com
```

这已经不是普通的 `https://example.com` URL 结构了。它更适合作为另一个 URL 的参数值，例如：

```
const redirectUrl = "https://example.com/login?next=" +
  encodeURIComponent("https://example.com/dashboard");
```

### 2. 不要重复编码

```
const once = encodeURIComponent("hello world");
// hello%20world

const twice = encodeURIComponent(once);
// hello%2520world
```

第二次编码时，`%` 被编码成了 `%25`，于是 `%20` 变成 `%2520`。这通常会导致数据恢复时出现问题。

### 3. 编码不等于安全过滤

URI 编码的目的是正确表示字符串，不是替代输入校验、权限检查或防止所有注入攻击。安全处理仍应结合具体使用场景完成。

## 总结

| 方法 | 处理对象 | 是否保留 URL 结构符号 | 常见用途 |
| --- | --- | --- | --- |
| `encodeURI` | 完整 URI | 是 | 编码完整 URL 中需要编码的字符 |
| `encodeURIComponent` | URI 的一个组成部分 | 否，更多分隔符会被编码 | 编码查询参数值、路径参数值等 |

简单来说，`encodeURI("https://...")` 编码后仍像一个 URL，是因为它保留了 URL 的结构字符；`encodeURIComponent("https://...")` 会把这些结构字符也编码，因此结果看起来像一整段普通数据。查询参数的值优先使用 `URLSearchParams` 或 `encodeURIComponent`。

排序方式 :

### **成为第一条评论！**

Nobody's responded to this post yet. Add your thoughts and get the conversation going.

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://www.angryecho.com/c/qian_duan_she_qu/p/P2TBC14jbXSmIlt3EqFNf#post","@type":"DiscussionForumPosting","commentCount":0,"dateModified":"2026-11-02T02:55:56.867Z","datePublished":"2026-11-01T13:50:09.372Z","description":"encodeURI 和 encodeURIComponent 都用于对字符串进行百分号编码，但它们面向的对象不同： encodeURI：编码一个完整的 URI，同时尽量保留 URI 的结构符号。 encodeURIComponent：编码 URI 中的一个组成部分，例如查询参数的值。","headline":"encodeURI 和 encodeURIComponent 有什么区别？","isPartOf":"https://www.angryecho.com/c/qian_duan_she_qu","mainEntityOfPage":"https://www.angryecho.com/c/qian_duan_she_qu/p/P2TBC14jbXSmIlt3EqFNf","text":"encodeURI 和 encodeURIComponent 都用于对字符串进行百分号编码，但它们面向的对象不同：\n\n\n\n\n\nencodeURI：编码一个完整的 URI，同时尽量保留 URI 的结构符号。\n\n\n\nencodeURIComponent：编码 URI 中的一个组成部分，例如查询参数的值。\n\n所以，编码 https://example.com/a?x=1&y=2 时，两者结果不同是正常的。\n\n一、先看编码结果\n\nconst url = \"https://example.com/a?x=1&y=2\";\n\nconsole.log(encodeURI(url));\n// https://example.com/a?x=1&y=2\n\nconsole.log(encodeURIComponent(url));\n// https%3A%2F%2Fexample.com%2Fa%3Fx%3D1%26y%3D2\n\nencodeURI 编码后，URL 看起来还是一个完整的 URL，这是因为它保留了 URL 中用于分隔结构的字符，例如：\n\n: / ? & =\n\n而 encodeURIComponent 会把这些字符也编码掉。结果中的冒号、斜杠、问号、等号和 & 都变成了百分号编码。\n\n因此，encodeURIComponent 的结果看起来不再像一个可直接使用的 URL。它表示的是“整个 URL 字符串作为一个数据片段”，而不是保留 URL 结构后的地址。\n\n二、为什么需要两种方法？\n\nURL 不只是普通字符串，它有自己的结构。例如：\n\nhttps://example.com/search?q=JavaScript&sort=recent\n\n可以拆成：\n\n协议：       https:\n主机名：     example.com\n路径：       /search\n参数分隔符： ?\n参数：       q=JavaScript\n参数分隔符： &\n参数：       sort=recent\n\n在这个结构里，?、&、=、/ 等字符可能具有特殊含义。如果把它们全部保留或全部编码，结果会完全不同。\n\nencodeURI 适合处理整个 URI：尽可能保留这些结构符号。\n\nencodeURIComponent 适合处理URI 的某一个值：将值中的结构符号也编码，避免它们被误认为 URL 的分隔符。\n\n三、encodeURI 会保留哪些字符？\n\nencodeURI 通常会保留 URL 中有结构意义的字符，包括：\n\n; , / ? : @ & = + $ # -\n\n例如：\n\nencodeURI(\"https://example.com/search?q=hello world\");\n\n结果：\n\nhttps://example.com/search?q=hello%20world\n\nURL 的结构部分仍然保留，而空格被编码成 %20。\n\nencodeURI 的一个重要限制\n\nencodeURI 会保留 #，但 # 在 URL 中表示片段标识符。因此，字符串中的 # 可能会被浏览器当成 URL 片段的开始。\n\nconst url = \"https://example.com/search#tag\";\n\nconsole.log(encodeURI(url));\n// https://example.com/search#tag\n\n如果 # 本来是某个参数值中的普通字符，就不应该直接依赖 encodeURI 来处理整个 URL。应当对参数值单独编码。\n\n四、encodeURIComponent 会做什么？\n\nencodeURIComponent 会编码 URI 中具有结构意义的分隔符，例如：\n\n; , / ? : @ & = + $ #\n\n例如：\n\nconst value = \"https://example.com/a?x=1&y=2\";\n\nconsole.log(encodeURIComponent(value));\n// https%3A%2F%2Fexample.com%2Fa%3Fx%3D1%26y%3D2\n\n在这里，整个字符串被作为一个普通值处理。原有的 https://、? 和 & 不再作为 URL 结构符号存在。\n\n五、最常见的用法：编码查询参数的值\n\n假设要把用户输入放进查询参数：\n\nconst keyword = \"JavaScript & 前端\";\n\nconst url = \"https://example.com/search?q=\" + encodeURIComponent(keyword);\n\nconsole.log(url);\n// https://example.com/search?q=JavaScript%20%26%20%E5%89%8D%E7%AB%AF\n\n这里应该使用 encodeURIComponent，因为 keyword 是参数值。\n\n如果错误地使用 encodeURI：\n\nconst keyword = \"JavaScript & sort=recent\";\n\nconst url = \"https://example.com/search?q=\" + encodeURI(keyword);\n\n& 和 = 会被保留，拼出来的内容可能被解释成额外的查询参数：\n\nhttps://example.com/search?q=JavaScript%20&%20sort=recent\n\n这样就可能改变 URL 的含义。\n\n六、简单记忆\n\n可以这样记：\n\n\n\n处理完整 URL，考虑使用 encodeURI；处理 URL 中的某一个值，使用 encodeURIComponent。\n\n示例：\n\nconst fullUrl = \"https://example.com/search?q=hello world\";\n\n// 整个 URL\nencodeURI(fullUrl);\n\n// 参数值\nencodeURIComponent(\"hello world\");\n\n不过，实际项目中，拼接查询参数时通常更推荐使用 URLSearchParams，避免手动处理编码和分隔符。\n\n七、推荐做法：使用 URLSearchParams\n\nconst params = new URLSearchParams({\n  q: \"JavaScript & 前端\",\n  sort: \"recent\",\n});\n\nconst url = `https://example.com/search?${params.toString()}`;\n\nconsole.log(url);\n// https://example.com/search?q=JavaScript+%26+%E5%89%8D%E7%AB%AF&sort=recent\n\nURLSearchParams 会处理参数值的编码，并正确构造查询字符串。对于普通的查询参数场景，通常比手动拼接字符串更安全、清晰。\n\n也可以基于 URL 对象构造地址：\n\nconst url = new URL(\"https://example.com/search\");\nurl.searchParams.set(\"q\", \"JavaScript & 前端\");\nurl.searchParams.set(\"sort\", \"recent\");\n\nconsole.log(url.toString());\n\n八、空格编码：%20 与 +\n\nencodeURI 和 encodeURIComponent 通常会把空格编码成：\n\n%20\n\n而 URLSearchParams 在序列化查询参数时，可能会把空格表示为：\n\n+\n\n例如：\n\nnew URLSearchParams({ q: \"hello world\" }).toString();\n// q=hello+world\n\n这两种形式常见于不同的 URL 编码场景。处理查询参数时，优先使用 URLSearchParams，不要为了统一格式而随意手动替换。\n\n九、几个常见误区\n\n1. 不要用 encodeURIComponent 编码整个 URL 后直接访问\n\nconst encoded = encodeURIComponent(\"https://example.com\");\n\n结果会变成：\n\nhttps%3A%2F%2Fexample.com\n\n这已经不是普通的 https://example.com URL 结构了。它更适合作为另一个 URL 的参数值，例如：\n\nconst redirectUrl = \"https://example.com/login?next=\" +\n  encodeURIComponent(\"https://example.com/dashboard\");\n\n2. 不要重复编码\n\nconst once = encodeURIComponent(\"hello world\");\n// hello%20world\n\nconst twice = encodeURIComponent(once);\n// hello%2520world\n\n第二次编码时，% 被编码成了 %25，于是 %20 变成 %2520。这通常会导致数据恢复时出现问题。\n\n3. 编码不等于安全过滤\n\nURI 编码的目的是正确表示字符串，不是替代输入校验、权限检查或防止所有注入攻击。安全处理仍应结合具体使用场景完成。\n\n总结\n\n\n\n\n\n\n\n方法\n\n\n\n处理对象\n\n\n\n是否保留 URL 结构符号\n\n\n\n常见用途\n\n\n\n\n\nencodeURI\n\n\n\n完整 URI\n\n\n\n是\n\n\n\n编码完整 URL 中需要编码的字符\n\n\n\n\n\nencodeURIComponent\n\n\n\nURI 的一个组成部分\n\n\n\n否，更多分隔符会被编码\n\n\n\n编码查询参数值、路径参数值等\n\n简单来说，encodeURI(\"https://...\") 编码后仍像一个 URL，是因为它保留了 URL 的结构字符；encodeURIComponent(\"https://...\") 会把这些结构字符也编码，因此结果看起来像一整段普通数据。查询参数的值优先使用 URLSearchParams 或 encodeURIComponent。","url":"https://www.angryecho.com/c/qian_duan_she_qu/p/P2TBC14jbXSmIlt3EqFNf","author":{"@type":"Person","name":"excel","url":"https://www.angryecho.com/u/F2Oexcel"},"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/DislikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ShareAction","userInteractionCount":0}]}]}
```

## Sitemap

See the full [sitemap](https://www.angryecho.com/sitemap.md) for all pages.
