aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/api/windowbase64/btoa/index.html
blob: 6b742198a5fd0f4ed349f0ef29b2ada388757c9c (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
---
title: WindowOrWorkerGlobalScope.btoa()
slug: Web/API/WindowBase64/btoa
tags:
  - API
  - Base64
  - Web
  - WindowOrWorkerGlobalScope
  - 参考
  - 字符串
  - 数据
  - 方法
translation_of: Web/API/WindowOrWorkerGlobalScope/btoa
---
<p>{{APIRef("HTML DOM")}}</p>

<p><strong><code>WindowOrWorkerGlobalScope.btoa()</code> </strong>{{jsxref("String")}} 对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节。</p>

<div class="note">
<p><strong>Note</strong>: 由于这个函数将每个字符视为二进制数据的字节,而不管实际组成字符的字节数是多少,所以如果任何字符的{{Glossary("code point", "码位")}}超出 <code>0x00</code> ~ <code>0xFF</code> 这个范围,则会引发 <code>InvalidCharacterError</code> 异常。请参阅 {{anch("Unicode_字符串")}} ,该示例演示如何编码含有码位超出 <code>0x00</code> ~ <code>0xFF</code> 范围的字符的字符串。</p>
</div>

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

<pre class="syntaxbox">let encodedData = window.btoa(<var>stringToEncode</var>);
</pre>

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

<dl>
 <dt><code>stringToEncode</code></dt>
 <dd>一个字符串, 其字符分别表示要编码为 ASCII 的二进制数据的单个字节。</dd>
</dl>

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

<p>一个包含 <code>stringToEncode</code> 的 Base64 表示的字符串。</p>

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

<pre class="brush: js">let encodedData = window.btoa("Hello, world"); // 编码
let decodedData = window.atob(encodedData);    // 解码
</pre>

<h2 id="备注">备注</h2>

<p>你可以使用此方法对可能导致通信问题的数据进行编码,传输,然后使用 <code>{{domxref("WindowOrWorkerGlobalScope.atob","atob()")}}</code> 方法再次解码数据。例如,可以编码控制字符,包括 ASCII 值为 0 到 31 的字符。</p>

<p>在用 JavaScript 编写 XPCOM 组件时,<code>btoa()</code> 方法也是可用的,虽然全局对象已经不是 {{domxref("Window")}} 了。</p>

<h2 id="Unicode_字符串">Unicode 字符串</h2>

<p>在多数浏览器中,使用 <code>btoa()</code> 对 Unicode 字符串进行编码都会触发 <code>InvalidCharacterError</code> 异常。</p>

<p>一种选择是转义任何扩展字符,以便实际编码的字符串是原始字符的 ASCII 表示形式。考虑这个例子,代码来自 <a href="http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html">Johan Sundström</a></p>

<pre class="brush: js" id="txt">// ucs-2 string to base64 encoded ascii
function utoa(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}
// base64 encoded ascii to ucs-2 string
function atou(str) {
    return decodeURIComponent(escape(window.atob(str)));
}
// Usage:
utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"

utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
</pre>

<p dir="ltr" id="tw-target-text">更好、更可靠、性能更优异的解决方案是使用类型化数组进行转换。</p>

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

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">备注</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('HTML WHATWG', '#dom-btoa', 'WindowOrWorkerGlobalScope.btoa()')}}</td>
   <td>{{Spec2('HTML WHATWG')}}</td>
   <td>Method moved to the <code>WindowOrWorkerGlobalScope</code> mixin in the latest spec.</td>
  </tr>
  <tr>
   <td>{{SpecName('HTML5.1', '#dom-windowbase64-btoa', 'WindowBase64.btoa()')}}</td>
   <td>{{Spec2('HTML5.1')}}</td>
   <td>Snapshot of {{SpecName("HTML WHATWG")}}. No change.</td>
  </tr>
  <tr>
   <td>{{SpecName("HTML5 W3C", "#dom-windowbase64-btoa", "WindowBase64.btoa()")}}</td>
   <td>{{Spec2('HTML5 W3C')}}</td>
   <td>Snapshot of {{SpecName("HTML WHATWG")}}. Creation of <code>WindowBase64</code> (properties where on the target before it).</td>
  </tr>
 </tbody>
</table>

<h2 id="Polyfill">Polyfill</h2>

<pre class="brush: js">// Polyfill from  <a href="https://github.com/MaxArt2501/base64-js/blob/master/base64.js">https://github.com/MaxArt2501/base64-js/blob/master/base64.js
</a>(function() {
    // base64 character set, plus padding character (=)
    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

        // Regular expression to check formal correctness of base64 encoded strings
        b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;

    window.btoa = window.btoa || function(string) {
        string = String(string);
        var bitmap, a, b, c,
            result = "",
            i = 0,
            rest = string.length % 3; // To determine the final padding

        for (; i &lt; string.length;) {
            if ((a = string.charCodeAt(i++)) &gt; 255 ||
                (b = string.charCodeAt(i++)) &gt; 255 ||
                (c = string.charCodeAt(i++)) &gt; 255)
                throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");

            bitmap = (a &lt;&lt; 16) | (b &lt;&lt; 8) | c;
            result += b64.charAt(bitmap &gt;&gt; 18 &amp; 63) + b64.charAt(bitmap &gt;&gt; 12 &amp; 63) +
                b64.charAt(bitmap &gt;&gt; 6 &amp; 63) + b64.charAt(bitmap &amp; 63);
        }

        // If there's need of padding, replace the last 'A's with equal signs
        return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
    };

    window.atob = window.atob || function(string) {
        // atob can work with strings with whitespaces, even inside the encoded part,
        // but only \t, \n, \f, \r and ' ', which can be stripped.
        string = String(string).replace(/[\t\n\f\r ]+/g, "");
        if (!b64re.test(string))
            throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");

        // Adding the padding if missing, for semplicity
        string += "==".slice(2 - (string.length &amp; 3));
        var bitmap, result = "",
            r1, r2, i = 0;
        for (; i &lt; string.length;) {
            bitmap = b64.indexOf(string.charAt(i++)) &lt;&lt; 18 | b64.indexOf(string.charAt(i++)) &lt;&lt; 12 |
                (r1 = b64.indexOf(string.charAt(i++))) &lt;&lt; 6 | (r2 = b64.indexOf(string.charAt(i++)));

            result += r1 === 64 ? String.fromCharCode(bitmap &gt;&gt; 16 &amp; 255) :
                r2 === 64 ? String.fromCharCode(bitmap &gt;&gt; 16 &amp; 255, bitmap &gt;&gt; 8 &amp; 255) :
                String.fromCharCode(bitmap &gt;&gt; 16 &amp; 255, bitmap &gt;&gt; 8 &amp; 255, bitmap &amp; 255);
        }
        return result;
    };
})()
</pre>

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

<p>{{Compat("api.WindowOrWorkerGlobalScope.btoa")}}</p>

<h2 id="参见">参见</h2>

<ul>
 <li>{{domxref("WindowBase64/Base64_encoding_and_decoding", "Base64 encoding and decoding")}}</li>
 <li><a href="/zh-CN/docs/data_URIs"><code>data</code> URI</a></li>
 <li>{{domxref("WindowOrWorkerGlobalScope.atob","atob()")}}</li>
 <li><a href="/zh-CN/docs/Components.utils.importGlobalProperties">Components.utils.importGlobalProperties</a></li>
</ul>