aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/api/windoworworkerglobalscope/btoa/index.html
blob: 93d63b601063ea018ccf11d58e40be2587b22296 (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
---
title: WindowOrWorkerGlobalScope.btoa()
slug: Web/API/WindowOrWorkerGlobalScope/btoa
translation_of: Web/API/WindowOrWorkerGlobalScope/btoa
---
<p>{{APIRef("HTML DOM")}}</p>

<p>The <code><strong>WindowOrWorkerGlobalScope.btoa()</strong></code> method creates a {{glossary("Base64")}}-encoded ASCII string from a <a href="/en-US/docs/Web/API/DOMString/Binary">binary string</a> (i.e., a {{jsxref("String")}} object in which each character in the string is treated as a byte of binary data).</p>

<p>You can use this method to encode data which may otherwise cause communication problems, transmit it, then use the {{domxref("WindowOrWorkerGlobalScope.atob", "atob()")}} method to decode the data again. For example, you can encode control characters such as ASCII values 0 through 31.</p>

<h2 id="Syntax">Syntax</h2>

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

<h3 id="Parameters">Parameters</h3>

<dl>
 <dt><code><var>stringToEncode</var></code></dt>
 <dd>The <a href="/en-US/docs/Web/API/DOMString/Binary">binary string</a> to encode.</dd>
</dl>

<h3 id="Return_value">Return value</h3>

<p>An ASCII string containing the Base64 representation of <code><var>stringToEncode</var></code>.</p>

<h3 id="Exceptions">Exceptions</h3>

<dl>
 <dt><code>InvalidCharacterError</code></dt>
 <dd>The string contained a character that did not fit in a single byte. See "Unicode strings" below for more detail.</dd>
</dl>

<h2 id="Example">Example</h2>

<pre class="brush:js notranslate">const encodedData = window.btoa('Hello, world'); // encode a string
const decodedData = window.atob(encodedData); // decode the string
</pre>

<h2 id="Unicode_strings">Unicode strings</h2>

<p>The <code>btoa()</code> function takes a JavaScript string as a parameter. In JavaScript strings are represented using the UTF-16 character encoding: in this encoding, strings are represented as a sequence of 16-bit (2 byte) units. Every ASCII character fits into the first byte of one of these units, but many other characters don't.</p>

<p>Base64, by design, expects binary data as its input. In terms of JavaScript strings, this means strings in which each character occupies only one byte. So if you pass a string into <code>btoa()</code> containing characters that occupy more than one byte, you will get an error, because this is not considered binary data:</p>

<pre class="brush: js notranslate">const ok = "a";
console.log(ok.codePointAt(0).toString(16)); //   61: occupies &lt; 1 byte

const notOK = "✓"
console.log(notOK.codePointAt(0).toString(16)); // 2713: occupies &gt; 1 byte

console.log(btoa(ok));    // YQ==
console.log(btoa(notOK)); // error</pre>

<p>If you need to encode Unicode text as ASCII using <code>btoa()</code>, one option is to convert the string such that each 16-bit unit occupies only one byte. For example:</p>

<pre class="brush: js notranslate">// convert a Unicode string to a string in which
// each 16-bit unit occupies only one byte
function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i &lt; codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}

// a string that contains characters occupying &gt; 1 byte
const myString = "☸☹☺☻☼☾☿";

const converted = toBinary(myString);
const encoded = btoa(converted);
console.log(encoded);                 // OCY5JjomOyY8Jj4mPyY=
</pre>

<p>If you do this, of course you'll have to reverse the conversion on the decoded string:</p>

<pre class="brush: js language-js notranslate">function fromBinary(binary) {
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i &lt; bytes.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint16Array(bytes.buffer));
}

const decoded = atob(encoded);
const original = fromBinary(decoded);
console.log(original);                // ☸☹☺☻☼☾☿
</pre>

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

<p>You can use a 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> for browsers that don't support it.</p>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</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="Browser_compatibility">Browser compatibility</h2>

<div>


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

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs"><code>data</code> URIs</a></li>
 <li>{{domxref("WindowOrWorkerGlobalScope.atob","atob()")}}</li>
</ul>