aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/encodeuricomponent/index.html
blob: d80cd457c97ea1e74a43322207e3299d6b34310c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
---
title: encodeURIComponent()
slug: Web/JavaScript/Reference/Global_Objects/encodeURIComponent
tags:
  - JavaScript
  - URI
  - 统一资源标识符
translation_of: Web/JavaScript/Reference/Global_Objects/encodeURIComponent
---
<div>{{jsSidebar("Objects")}}</div>

<p><code><strong>encodeURIComponent()</strong></code>函数通过将一个,两个,三个或四个表示字符的UTF-8编码的转义序列替换某些字符的每个实例来编码 <a href="https://wiki.developer.mozilla.org/en-US/docs/Glossary/URI">URI</a> (对于由两个“代理”字符组成的字符而言,将仅是四个转义序列) 。</p>

<p>{{EmbedInteractiveExample("pages/js/globalprops-encodeuricomponent.html","shorter")}}</p>

<h2 id="语法">语法</h2>

<pre class="syntaxbox notranslate">encodeURIComponent(str);</pre>

<h3 id="参数">参数</h3>

<dl>
 <dt><code>str</code></dt>
 <dd>String. URI 的组成部分。</dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>原字串作为URI组成部分被被编码后的新字符串。</p>

<h2 id="描述">描述</h2>

<p><code>encodeURIComponent</code> 转义除了如下所示外的所有字符:</p>

<pre class="notranslate">不转义的字符:
    A-Z a-z 0-9 <code>-</code> <code>_</code> <code>.</code> <code>!</code> <code>~</code> <code>*</code> <code>'</code> <code>(</code> <code>)</code></pre>

<p><code>encodeURIComponent()</code> 和 <strong><code>encodeURI</code></strong> 有以下几个不同点:</p>

<pre class="notranslate">var set1 = ";,/?:@&amp;=+$";  // 保留字符
var set2 = "-_.!~*'()";   // 不转义字符
var set3 = "#";           // 数字标志
var set4 = "ABC abc 123"; // 字母数字字符和空格

console.log(encodeURI(set1)); // ;,/?:@&amp;=+$
console.log(encodeURI(set2)); // -_.!~*'()
console.log(encodeURI(set3)); // #
console.log(encodeURI(set4)); // ABC%20abc%20123 (the space gets encoded as %20)

console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24
console.log(encodeURIComponent(set2)); // -_.!~*'()
console.log(encodeURIComponent(set3)); // %23
console.log(encodeURIComponent(set4)); // ABC%20abc%20123 (the space gets encoded as %20)</pre>

<p>注意,如果试图编码一个非高-低位完整的代理字符,将会抛出一个 {{jsxref("URIError")}} 错误,例如:</p>

<pre class="brush: js notranslate">// 高低位完整
alert(encodeURIComponent('\uD800\uDFFF'));

// 只有高位,将抛出"URIError: malformed URI sequence"
alert(encodeURIComponent('\uD800'));

// 只有低位,将抛出"URIError: malformed URI sequence"
alert(encodeURIComponent('\uDFFF')); </pre>

<p>为了避免服务器收到不可预知的请求,对任何用户输入的作为URI部分的内容你都需要用encodeURIComponent进行转义。比如,一个用户可能会输入"<code>Thyme &amp;time=again</code>"作为<code>comment</code>变量的一部分。如果不使用encodeURIComponent对此内容进行转义,服务器得到的将是<code>comment=Thyme%20&amp;time=again</code>。请注意,"&amp;"符号和"="符号产生了一个新的键值对,所以服务器得到两个键值对(一个键值对是<code>comment=Thyme</code>,另一个则是<code>time=again</code>),而不是一个键值对。</p>

<p>对于 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#application/x-www-form-urlencoded-encoding-algorithm"><code>application/x-www-form-urlencoded</code></a> (POST) 这种数据方式,空格需要被替换成 '+',所以通常使用 <code>encodeURIComponent</code> 的时候还会把 "%20" 替换为 "+"。</p>

<p>为了更严格的遵循 <a class="external" href="http://tools.ietf.org/html/rfc3986">RFC 3986</a>(它保留 !, ', (, ), 和 *),即使这些字符并没有正式划定 URI 的用途,下面这种方式是比较安全的:</p>

<pre class="brush: js notranslate">function fixedEncodeURIComponent (str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}</pre>

<h2 id="示例">示例</h2>

<p>下面这个例子提供了 UTF-8 下 <code>Content-Disposition</code><code>Link</code> 的服务器响应头信息的参数(例如 UTF-8 文件名):</p>

<pre class="brush: js notranslate">var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''"
             + encodeRFC5987ValueChars(fileName);

console.log(header);
// 输出 "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"


function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // 注意,仅管 RFC3986 保留 "!",但 RFC5987 并没有
        // 所以我们并不需要过滤它
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // 下面的并不是 RFC5987 中 URI 编码必须的
            // 所以对于 |`^ 这3个字符我们可以稍稍提高一点可读性
            replace(/%(?:7C|60|5E)/g, unescape);
}
</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">备注</th>
  </tr>
  <tr>
   <td>{{SpecName('ES3')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td>初始定义</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.1.3.4', 'encodeURIComponent')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-encodeuricomponent-uricomponent', 'encodeURIComponent')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-encodeuricomponent-uricomponent', 'encodeURIComponent')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<p>{{Compat("javascript.builtins.encodeURIComponent")}}</p>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li>{{jsxref("decodeURI")}}</li>
 <li>{{jsxref("encodeURI")}}</li>
 <li>{{jsxref("decodeURIComponent")}}</li>
</ul>