recursal/MDN huggingface dataset:
FormData()
==========

**`FormData()`** 构造函数用于创建一个新的`FormData`对象。

**备注：** 该功能在 Web Workers 中可用。

语法
--


```js
new FormData(form)
```

### 参数

`form` 可选

一个 HTML 上的`<form>`表单元素——当指定了，这种方式创建的`FormData`对象会自动将 form 中的表单值也包含进去，包括文件内容也会被编码之后包含进去。

例子
--

下面的代码将创建一个空的 FormData 对象：


```js
var formData = new FormData(); // 当前为空
```


你可以使用`FormData.append`来添加键/值对到表单里面；


```js
formData.append("username", "Chris");
```


或者你可以使用可选的 `form` 参数来创建一个带预置数据的 FormData 对象：


```html
<form id="myForm" name="myForm">
  <div>
    <label for="username">Enter name:</label>
    <input type="text" id="username" name="username" />
  </div>
  <div>
    <label for="useracc">Enter account number:</label>
    <input type="text" id="useracc" name="useracc" />
  </div>
  <div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile" />
  </div>
  <input type="submit" value="Submit!" />
</form>
```


**备注：** 所有的输入元素都需要有 **name** 属性，否则无法访问到值。


```js
var myForm = document.getElementById("myForm");
formData = new FormData(myForm);
```

规范
--

| Specification |
| --- |
| XMLHttpRequest Standard # dom-formdata |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

附注
--

在 Gecko 7.0 之前，如果你将`Blob`作为数据添加到 form 对象中，文件名就是空的，这可能导致服务器在 HTTP 头的 Content-Disposition 中设置的文件名为空而引起错误。从 Gecko 7.0 开始，将会使用"blob"作为 Blob 数据的文件名。

参见
--

* 使用 FormData 对象
* `<form>`
FormData.keys()
===============

**`FormData.keys()`** 该方法返回一个迭代器（`iterator`），遍历了该 formData 包含的所有 key，这些 key 是 `USVString` 对象。

**备注：** 该方法在 Web Workers 可用。

语法
--


```js
formData.keys();
```

### 返回值

返回一个迭代器（ `iterator`）。

示例
--


```js
// 先创建一个 FormData 对象
var formData = new FormData();
formData.append("key1", "value1");
formData.append("key2", "value2");

// 输出所有的 key
for (var key of formData.keys()) {
  console.log(key);
}
```


结果如下：
```

key1
key2
```

规范
--

#### No specification found

No specification data found for `api.FormData.keys`.  
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 FormData 对象
* `<form>`
FormData.append()
=================

`FormData` 接口的 **`append()`** 方法会添加一个新值到 `FormData` 对象内的一个已存在的键中，如果键不存在则会添加该键。

`FormData.set` 和 `append()` 的区别在于，如果指定的键已经存在， `FormData.set` 会使用新值覆盖已有的值，而 `append()` 会把新值添加到已有值集合的后面。

**备注：** 这个方法在 Web Workers 中可用。

语法
--

这个方法有两个版本：一个有两个参数的版本和一个有三个参数的版本。


```js
formData.append(name, value);
formData.append(name, value, filename);
```

### 参数

`name`

`value` 中包含的数据对应的表单名称。

`value`

`表单的值。`可以是`USVString` 或 `Blob` (包括子类型，如 `File`)。

`filename` 可选

传给服务器的文件名称 (一个 `USVString`), 当一个 `Blob` 或 `File` 被作为第二个参数的时候， `Blob` 对象的默认文件名是 "blob"。 `File` 对象的默认文件名是该文件的名称。


**备注：** 如果你指定一个 `Blob` 作为数据添加到 `FormData` 对象中，文件名会被放在 "Content-Disposition" 头部（常常会根据浏览器变化而变化）传给服务器。

### 返回值

空

示例
--

下面的代码创建了一个空的 `FormData` 对象：


```js
var formData = new FormData(); // Currently empty
```


你可以通过 `FormData.append` 往对象里加入键值对：


```js
formData.append("username", "Chris");
formData.append("userpic", myFileInput.files[0], "chris.jpg");
```


跟常规`表单数据一样，你可以使用同一个名称添加多个值` 。例如 (为了与 PHP 命名习惯一致在名称中添加了 [])：


```js
formData.append("userpic[]", myFileInput1.files[0], "chris1.jpg");
formData.append("userpic[]", myFileInput2.files[0], "chris2.jpg");
```


这项技术使得多文件上传的处理更加简单，因为所得数据结构更有利于循环。

规范
--

| Specification |
| --- |
| XMLHttpRequest Standard # dom-formdata-append |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 FormData 对象
* `<form>`
FormData.getAll()
=================

**`getAll()`** 方法会返回该 `FormData` 对象指定 key 的所有值。

**备注：** 该方法在 Web Workers 中可用。

语法
--


```js
formData.getAll(name);
```

### 参数

`name`

一个 `USVString` 表示要检索的 key 名称。

### 返回

一个 `FormDataEntryValue` (en-US) 数组。

示例
--

下列代码会先创建一个空的 `FormData` 对象：


```js
var formData = new FormData();
```


使用 `FormData.append` 添加两个 `username 的值：`


```js
formData.append("username", "Chris");
formData.append("username", "Bob");
```


下列 `getAll()` 方法会返回一个数组，包含了所有 `username` 的值：


```js
formData.getAll("username"); // Returns ["Chris", "Bob"]
```

规范
--

| Specification |
| --- |
| XMLHttpRequest Standard # dom-formdata-getall |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 FormData 对象
* `<form>`
FormData.values()
=================

**`FormData.values()`** 方法返回一个允许遍历该对象中所有值的 `迭代器` 。这些值是 `USVString` 或是`Blob` 对象。

**备注：** 此方法在 Web Workers 中可用

语法
--


```js
formData.values();
```

### 返回值

返回一个`迭代器`.

示例
--


```js
//创建一个 FormData 测试对象
var formData = new FormData();
formData.append("key1", "value1");
formData.append("key2", "value2");

//显示值
for (var value of formData.values()) {
  console.log(value);
}
```


结果为：
```

value1
value2
```

规范
--

#### No specification found

No specification data found for `api.FormData.values`.  
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 FormData 对象
* `<form>`
FormData.set()
==============

**`set()`** 方法会对 `FormData` 对象里的某个 `key` 设置一个新的值，如果该 `key` 不存在，则添加。

`set()` 和 `FormData.append` 不同之处在于：如果某个 key 已经存在，`set()` 会直接覆盖所有该 key 对应的值，而 `FormData.append` 则是在该 key 的最后位置再追加一个值。

**备注：** 该方法在 Web Workers 可用。

语法
--

该方法有两种使用方式，一个是传入两个参数，一个是传入三个参数。


```js
formData.set(name, value);
formData.set(name, value, filename);
```


#### 参数

`name`

字段名称。

`value`

字段的值，该值可以是一个 `USVString` 或 `Blob`（包括其子类，例如 `File`），如果不是这两个指定的类型，其将被转成一个字符串。

`filename` 可选

 当第二个参数传递的是一个 blob 对象（`Blob`）或者 file 对象（`File`），filename 参数就代表传给服务端的文件名（一个 `USVString`）。
 `Blob` 对象的默认文件名是 "blob"，`File` 对象的默认文件名则为其“name”属性



**备注：** 如果对 FormData 对象插入一个 blob 对象（ `Blob`），那么发送给服务器的请求头部（header）里的“Content-Disposition”里的文件名称将会根据浏览器的不同而不同。

示例
--

先创建一个空的 `FormData` 对象：


```js
var formData = new FormData(); // Currently empty
```


使用 `FormData.set` 设置键/值：


```js
formData.set("username", "Chris");
formData.set("userpic", myFileInput.files[0], "chris.jpg");
```

规范
--

| Specification |
| --- |
| XMLHttpRequest Standard # dom-formdata-set |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 FormData 对象
* `<form>`
FormData.delete()
=================

`FormData` 接口的 **`delete()`** 方法会从 `FormData` 对象中删除指定键，即 key，和它对应的值，即 value。

**备注：** 此方法可用于 Web Workers。

语法
--


```js
formData.delete(name);
```

### 参数

`name`

要删除的键（Key）的名字。

### 返回

空。

例子
--

以下代码将会创建一个空的 `FormData` 对象，并且从指定的表单中获取键值对：


```js
var formData = new FormData(myForm);
```


你可以通过 `delete()` 方法来删除键值对：


```js
formData.delete("username");
```

规范
--

| Specification |
| --- |
| XMLHttpRequest Standard # dom-formdata-delete |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `XMLHTTPRequest`
* 使用 XMLHttpRequest
* 使用 FormData 对象
* `<form>`
FetchEvent.clientId
===================

`FetchEvent` 接口的 **`clientId`** 只读属性，返回由当前 service worker 正在控制的 `Client` 的 id。

然后可以将此 ID 传递给 `Clients.get()` 方法以检索相关联的客户端。

值
-

一个字符串，表示客户端的 ID。

示例
--


```js
self.addEventListener("fetch", (event) => {
  console.log(event.clientId);
});
```

规范
--

| Specification |
| --- |
| Service Workers # fetch-event-clientid |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 Service Worker
* Service worker 基础代码示例
* 是否支持 ServiceWorker？
* `Promise`
* 使用 web worker
FetchEvent.respondWith()
========================

`FetchEvent` 接口的 **`respondWith()`** 方法阻止浏览器默认的 fetch 操作，并且允许由你自己为 `Response` 提供一个 promise。

在大多数情况下，你可以提供接收方理解的任何形式的响应。例如，如果是由 `<img>` 初始化的请求，起响应主体必须是图像数据。出于安全考虑，这里有一些全局的规则：

* 只有当 `fetchEvent.request` 对象的 `mode` 是“`no-cors`”，你才能返回 `type` 为“`opaque`”的 `Response` 对象。
* 只有当 `fetchEvent.request` 对象的 `mode` 是“`manual`”，你才能返回 `type` 为“`opaqueredirect`”的 `Response` 对象。
* 如果 `fetchEvent.request` 对象的 `mode` 是“`same-origin`”，你无法返回 `type` 为“`cors`”的 `Response` 对象。
### 指定资源的最终 URL

从 Firefox 59 开始，在 service worker 中向 `FetchEvent.respondWith()` 提供 `Response` 时，`Response.url` 的值将作为最终解析的 URL 传输给被拦截的网络请求。如果 `Response.url` 值是空的字符串，那么 `FetchEvent.request.url` (en-US) 将被用作最终的 URL。

过去，在所有情况下，一直使用 `FetchEvent.request.url` (en-US) 作为最终的 URL。提供的 `Response.url` 实际上被忽略了。

例如，这意味着，如果 service worker 拦截了一个样式表或者 worker 脚本，那么提供的 `Response.url` 将会用于解决任何与 `@import` 或 `importScripts()` 相关的子资源加载（Firefox bug 1222008）。

对于大多数网络请求的类型，此变更是没有影响的，因为你不能察觉到最终的 URL。然而，在一些方面确实很重要：

* 如果 `fetch()` 被拦截，那么你可以在结果的 `Response.url` 观察最终的结果。
* 如果 worker 脚本被拦截，那么最终的 URL 将用于设置 `self.location` (en-US) 并用作 worker 脚本相对 URL 的基本 URL。
* 如果样式表被拦截，那么最终 URL 被用作解决相对 `@import` 加载的基本 URL。

请注意 `Windows` 和 `iframes` 的导航请求不使用最终的 URL。HTML 规范处理导航重定向的方式是最终使用 `Window.location` 生成的请求 URL。这意味着网站在离线时仍然可以提供一个“备用”的网页视图，而无需更改用户可见的 URL。

语法
--


```js
respondWith(response)
```

### 参数

`response`

一个 `Response` 或者 `Promise`（兑现为一个 `Response`）。否则，Fetch 返回一个网络错误。

### 返回值

无（`undefined`）。

### 异常

`NetworkError` `DOMException`

如果 `FetchEvent.request.mode` 和 `Response.type` 值的某些组合触发网络错误，正如上面提到的“全局规则”，则返回该错误。

`InvalidStateError` `DOMException`

如果事件仍没有被派发或者 `respondWith()` 已经被调用，则返回该错误。

示例
--

这个 fetch 事件尝试从 cache API 返回一个响应，否则回落至网络请求。


```js
addEventListener("fetch", (event) => {
  // Prevent the default, and handle the request ourselves.
  event.respondWith(
    (async () => {
      // Try to get the response from a cache.
      const cachedResponse = await caches.match(event.request);
      // Return it if we found one.
      if (cachedResponse) return cachedResponse;
      // If we didn't find a match in the cache, use the network.
      return fetch(event.request);
    })(),
  );
});
```


**备注：** `caches.match()` 是一个语法糖。等效于在每个缓存上调用 `cache.match()`（按照 `caches.keys()` 的顺序）直到返回 `Response`。

规范
--

| Specification |
| --- |
| Service Workers # fetch-event-respondwith |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 Service Worker
* Is ServiceWorker ready?
* `Promise`
* Fetch API
FetchEvent.request
==================

`FetchEvent` 接口的只读属性 **`request`** 返回触发事件处理程序的 `Request`。

这个属性是非空的（自从 Firefox 46 版本开始）。如果一个请求不是由其他方式提供的，构造函数的 `options` 对象必须包含一个请求（request）（参见 `FetchEvent()` (en-US)）。

值
-

一个 `Request` 对象。

示例
--

来自 service worker fetch 示例的代码片段（fetch 示例的在线演示）。`onfetch` (en-US) 事件处理程序监听 `fetch` 事件。当被触发时，将最终会传递给受控页面的 promise 传递给 `FetchEvent.respondWith()`。该 promise 会用 `Cache` 中第一个匹配的 URL 请求来兑现。如果没有匹配，代码将从网络获取响应。

该代码还会处理 `fetch()` 操作抛出的异常。注意，HTTP 错误响应（例如 404）不会抛出异常。它将返回一个拥有适当错误代码集的正常的响应对象。


```js
self.addEventListener("fetch", (event) => {
  console.log("Handling fetch event for", event.request.url);

  event.respondWith(
    caches.match(event.request).then((response) => {
      if (response) {
        console.log("Found response in cache:", response);

        return response;
      }
      console.log("No response found in cache. About to fetch from network…");

      return fetch(event.request)
        .then((response) => {
          console.log("Response from network is:", response);

          return response;
        })
        .catch((error) => {
          console.error("Fetching failed:", error);

          throw error;
        });
    }),
  );
});
```

规范
--

| Specification |
| --- |
| Service Workers # fetch-event-request |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 使用 Service Worker
* Service worker 基础代码示例
* Is ServiceWorker ready?
* `Promise`
* 使用 web worker
RTCDTMFSender：tonechange 事件
===========================

**`tonechange`** 事件会被 WebRTC API 发送给 `RTCDTMFSender` (en-US)，以指示先前（通过调用 `RTCDTMFSender.insertDTMF()` (en-US)）排队等待发送的 DTMF (en-US) 音调何时开始和结束。

要确定哪个音调开始播放，或者音调是否停止播放，请检查事件的 `tone` (en-US) 属性的值。

此事件不可取消，也不会冒泡。

语法
--

在像 `addEventListener()` 这样的方法中使用事件名称，或设置事件处理器属性。


```js
addEventListener("tonechange", (event) => {});

ontonechange = (event) => {};
```

事件类型
----

一个 `RTCDTMFToneChangeEvent` (en-US)。继承自 `Event`。

Event

RTCDTMFToneChangeEvent

(en-US)事件属性
----

*除了 `Event` 的属性外，此接口还提供以下属性：*

`RTCDTMFToneChangeEvent.tone` (en-US) 只读 

一个字符串，指定已开始播放的音调，或者如果上一个音调已完成播放，则为空字符串（`""`）。

示例
--

此示例建立了一个处理 `tonechange` 事件的处理器，它会更新一个元素以在其内容中显示当前播放的音调，或者，如果所有音调都已播放，则显示字符串 "<none>"。

这可以使用 `addEventListener()` 来完成：


```js
dtmfSender.addEventListener(
  "tonechange",
  (ev) => {
    let tone = ev.tone;
    if (tone === "") {
      tone = "&lt;none&gt;";
    }

    document.getElementById("playingTone").innerText = tone;
  },
  false,
);
```


你还可以直接设置 `ontonechange` 事件处理器属性：


```js
dtmfSender.ontonechange = (ev) => {
  let tone = ev.tone;
  if (tone === "") {
    tone = "&lt;none&gt;";
  }

  document.getElementById("playingTone").innerText = tone;
};
```

规范
--

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # event-RTCDTMFSender-tonechange |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.
SpeechSynthesisUtterance.voice
==============================

The **`voice`** property of the `SpeechSynthesisUtterance` (en-US) interface gets and sets the voice that will be used to speak the utterance.

This should be set to one of the `SpeechSynthesisVoice` (en-US) objects returned by `SpeechSynthesis.getVoices()`. If not set by the time the utterance is spoken, the voice used will be the most suitable default voice available for the utterance's `lang` (en-US) setting.

Syntax
------
```

var myVoice = speechSynthesisUtteranceInstance.voice;
speechSynthesisUtteranceInstance.voice = speechSynthesisVoiceInstance;
```

### Value

A `SpeechSynthesisVoice` (en-US) object.

Examples
--------


```js
var synth = window.speechSynthesis;

var inputForm = document.querySelector('form');
var inputTxt = document.querySelector('input');
var voiceSelect = document.querySelector('select');

var voices = synth.getVoices();

  ...

inputForm.onsubmit = function(event) {
  event.preventDefault();

  var utterThis = new SpeechSynthesisUtterance(inputTxt.value);
  var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
  for(i = 0; i < voices.length ; i++) {
    if(voices[i].name === selectedOption) {
      utterThis.voice = voices[i];
    }
  }
  synth.speak(utterThis);
  inputTxt.blur();
}
```

Specifications
--------------

| Specification |
| --- |
| Web Speech API # dom-speechsynthesisutterance-voice |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Speech API
GPUCanvasContext：configure() 方法
===============================

**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

`GPUCanvasContext` 接口的 **`configure()`** 方法使用给定的 `GPUDevice` 配置用于渲染的上下文。当调用时，将首先清除画布为透明的黑色。

语法
--


```js
configure(configuration)
```

### 参数

`configuration`

一个包含以下属性的对象：

`alphaMode` 可选

枚举值，用于指定 alpha 值，在读取、显示或用作图像源的纹理时，该值会对通过 `getCurrentTexture()` (en-US) 返回的纹理内容产生影响。

* `opaque`：忽略 alpha 值——如果纹理是透明的，当它用作图像源或显示到屏幕上时，将清除 alpha 通道为 1.0。这是默认值。
* `premultiplied`：颜色值会与它们的 alpha 值预乘。例如，在 50% alpha 下的 100% 红色是 `[0.5, 0, 0, 0.5]`。

`colorSpace` 可选

`getCurrentTexture()` 返回的纹理中写入的值应该使用哪种颜色空间来显示。可能的值是 `srgb`（默认值）和 `display-p3`。

`device`

包含上下文渲染信息的 `GPUDevice`。

`format`

`getCurrentTexture()` 返回的纹理将有哪些格式。这可以是 `bgra8unorm`、`rgba8unorm` 或 `rgba16float`。对于当前系统最佳的 canvas 纹理格式是由 `GPU.getPreferredCanvasFormat()` 返回的。建议使用此方法——如果你在配置 canvas 上下文时不使用最佳格式，则可能会产生额外的开销，例如根据平台而异的额外纹理的复制。

`usage` 可选

指定由 `getCurrentTexture()` 返回的纹理允许使用方式的位标识 (en-US)。可能的值有：

* `GPUTextureUsage.COPY_SRC`：纹理可用于复制操作的源，例如，调用 `GPUCommandEncoder.copyTextureToBuffer()` (en-US) 方法时的 source 参数。
* `GPUTextureUsage.COPY_DST`：纹理可用于拷贝/写入操作的目标，例如，调用 `GPUCommandEncoder.copyTextureToTexture()` (en-US) 方法的 destination 参数。
* `GPUTextureUsage.RENDER_ATTACHMENT`：纹理可用于渲染通道中的颜色附件，例如，调用 `GPUCommandEncoder.beginRenderPass()` (en-US) 中要使用的颜色附件视图。`usage` 的默认值是 `GPUTextureUsage.RENDER_ATTACHMENT`，但请注意，如果明确设置了不同的值，则不会自动地包含它；在这种情况下，你需要去主动的添加。
* `GPUTextureUsage.TEXTURE_BINDING`：纹理可绑定以在着色器中用作采样纹理，例如，调用 `GPUDevice.createBindGroup()` (en-US) 的要使用的绑定组条目。
* `GPUTextureUsage.STORAGE_BINDING`：纹理可绑定以在着色器中用作存储纹理，例如，调用 `GPUDevice.createBindGroup()` (en-US) 的要使用的绑定组条目。

请注意，可以通过管道符分隔值来指定多种可能的用法，例如：


```js
usage: GPUTextureUsage.COPY\_SRC | GPUTextureUsage.RENDER\_ATTACHMENT;
```


`viewFormats` 可选

视图从 `getCurrentTexture()` 返回的纹理创建时可能使用的格式数组。有关所有可能的值，请参阅纹理格式。


### 返回值

无（`undefined`）。

示例
--


```js
const canvas = document.querySelector("#gpuCanvas");
const context = canvas.getContext("webgpu");

context.configure({
  device: device,
  format: navigator.gpu.getPreferredCanvasFormat(),
  alphaMode: "premultiplied",
});
```

规范
--

| Specification |
| --- |
| WebGPU # dom-gpucanvascontext-configure |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* WebGPU API
SubtleCrypto.generateKey()
==========================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

`SubtleCrypto` 接口的 **`generateKey()`** 方法用于生成新的密钥（用于对称加密算法）或密钥对（用于非对称加密算法）。

语法
--


```js
generateKey(algorithm, extractable, keyUsages)
```

### 参数

`algorithm`

一个对象，用于定义要生成的算法类型，并提供所需的参数。

* 对于 RSASSA-PKCS1-v1\_5、RSA-PSS 或 RSA-OAEP 算法：传递 `RsaHashedKeyGenParams` (en-US) 对象。
* 对于 ECDSA 或 ECDH 算法：传递 `EcKeyGenParams` (en-US) 对象。
* 对于 HMAC 算法：传递 `HmacKeyGenParams` (en-US) 对象。
* 对于 AES-CTR、AES-CBC、AES-GCM 或 AES-KW 算法：传递 `AesKeyGenParams` (en-US) 对象。

`extractable`

 一个布尔值，表示生成的密钥是否可被 `SubtleCrypto.exportKey()` 和
 `SubtleCrypto.wrapKey()` 方法导出。


`keyUsages`

一个数组，表示生成出来的密钥可被用于做什么，数组元素可能的值有：

* `encrypt`：密钥可用于加密消息。
* `decrypt`：密钥可用于解密消息。
* `sign`：密钥可用于对消息进行签名。
* `verify`：密钥可用于验证签名。
* `deriveKey`：密钥可用于派生新的密钥。
* `deriveBits`：密钥可用于派生比特序列。
* `wrapKey`：密钥可用于包装一个密钥。
* `unwrapKey`：密钥可用于解开一个密钥的包装。

### 返回值

一个 `Promise`，会兑现为 `CryptoKey`（用于对称加密算法）或 `CryptoKeyPair` (en-US)（用于非对称加密算法）。

### 异常

当发生以下几种异常时，promise 会被拒绝：

`SyntaxError` `DOMException`

当结果是类型为 `secret` 或 `private` 的加密密钥，但 `keyUsages` 参数为空时触发。

`SyntaxError` `DOMException`

当结果是加密密钥对 (en-US)，但它的 `privateKey.usages` 属性为空时触发。

示例
--

**备注：** 你可以在 Github 上尝试可用的示例。

### 生成 RSA 密钥对

以下代码生成 RSA-OAEP 加密密钥对。在 GitHub 上查看完整代码。


```js
let keyPair = await window.crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 4096,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  },
  true,
  ["encrypt", "decrypt"],
);
```

### 生成椭圆曲线密钥对

以下代码生成 ECDSA 签名密钥对。在 GitHub 上查看完整代码。


```js
let keyPair = await window.crypto.subtle.generateKey(
  {
    name: "ECDSA",
    namedCurve: "P-384",
  },
  true,
  ["sign", "verify"],
);
```

### 生成 HMAC 密钥

以下代码生成 HMAC 签名密钥。在 GitHub 上查看完整代码。


```js
let key = await window.crypto.subtle.generateKey(
  {
    name: "HMAC",
    hash: { name: "SHA-512" },
  },
  true,
  ["sign", "verify"],
);
```

### 生成 AES 密钥

以下代码生成 AES-GCM 加密密钥。在 GitHub 上查看完整代码。


```js
let key = await window.crypto.subtle.generateKey(
  {
    name: "AES-GCM",
    length: 256,
  },
  true,
  ["encrypt", "decrypt"],
);
```

规范
--

| Specification |
| --- |
| Web Cryptography API # SubtleCrypto-method-generateKey |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 加密密钥长度的建议。
* NIST 过度使用的加密算法和密钥长度。
SubtleCrypto.digest()
=====================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

`SubtleCrypto` 接口的 **`digest()`** 方法生成给定数据的摘要。摘要是从一些可变长的输入生成的短且具有固定长度的值。密码摘要应表现出抗冲突性，这意味着很难构造出具有相同摘要值的两个不同的输入。

它以使用的摘要算法的标识符和计算摘要的数据为参数。并返回一个 `Promise`，会兑现数据的摘要值。

语法
--


```js
digest(algorithm, data)
```

### 参数

`algorithm`

可以是一个字符串或一个仅有 `name` 字符串属性的对象。该字符串为使用的哈希函数的名称。支持的值有：

* `"SHA-1"`（请不要在加密应用程序中使用它）
* `"SHA-256"`
* `"SHA-384"`
* `"SHA-512"`

`data`

一个包含将计算摘要的数据的 `ArrayBuffer`、`TypedArray` 或 `DataView` 对象。

### 返回值

一个 `Promise`，会兑现一个包含摘要值的 `ArrayBuffer`。

支持的算法
-----

摘要算法（也称为加密哈希函数）将任意长度的数据块转换为固定长度的输出（通常比输入短得多）。其在密码学中有多种应用。

| 算法 | 输出长度（比特） | 块大小（比特） | 规范 |
| --- | --- | --- | --- |
| SHA-1 | 160 | 512 | FIPS 180-4 第 6.1 节 |
| SHA-256 | 256 | 512 | FIPS 180-4 第 6.2 节 |
| SHA-384 | 384 | 1024 | FIPS 180-4 第 6.5 节 |
| SHA-512 | 512 | 1024 | FIPS 180-4 第 6.4 节 |

**警告：** 现在，SHA-1 被认为是易受攻击的，不应将其用于加密应用程序。

**备注：** 如果你在寻找如何创建密钥散列消息认证码（HMAC），则需要改用 SubtleCrypto.sign() 方法。

示例
--

### 基本示例

此示例对消息进行编码，然后计算其 SHA-256 摘要，并打印摘要长度：


```js
const text =
  "An obscure body in the S-K System, your majesty. The inhabitants refer to it as the planet Earth.";

async function digestMessage(message) {
  const encoder = new TextEncoder();
  const data = encoder.encode(message);
  const hash = await crypto.subtle.digest("SHA-256", data);
  return hash;
}

digestMessage(text).then((digestBuffer) =>
  console.log(digestBuffer.byteLength),
);
```

### 将摘要转换为十六进制字符串

摘要以 `ArrayBuffer` 的形式返回，但为了进行比较和显示，通常会使用十六进制（hex）字符串的形式表示。此示例计算摘要，然后将 `ArrayBuffer` 转换为十六进制字符串：


```js
const text =
  "An obscure body in the S-K System, your majesty. The inhabitants refer to it as the planet Earth.";

async function digestMessage(message) {
  const msgUint8 = new TextEncoder().encode(message); // 编码为（utf-8）Uint8Array
  const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); // 计算消息的哈希值
  const hashArray = Array.from(new Uint8Array(hashBuffer)); // 将缓冲区转换为字节数组
  const hashHex = hashArray
    .map((b) => b.toString(16).padStart(2, "0"))
    .join(""); // 将字节数组转换为十六进制字符串
  return hashHex;
}

digestMessage(text).then((digestHex) => console.log(digestHex));
```

规范
--

| Specification |
| --- |
| Web Cryptography API # SubtleCrypto-method-digest |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

**备注：** Chrome 60 添加了对非 TLS 连接禁用 crypto.subtle 的特性。

参见
--

* SubtleCrypto 的非加密用途 (en-US)
* Chromium 安全来源规范
* FIPS 180-4 规定了 SHA 系列的摘要算法。
SubtleCrypto.decrypt()
======================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

`SubtleCrypto` 接口的 **`decrypt()`** 方法用于解密加密数据。它以用于解密的密钥、一些可选的额外参数，以及待解密的数据（也称为“密文”）为参数；返回一个 `Promise`，会兑现解密后的数据（也称为“明文”）。

语法
--


```js
decrypt(algorithm, key, data)
```

### 参数

`algorithm`

一个对象，用于指定使用的算法，以及任何需要的额外参数。额外提供的参数的值必须与对应的 `encrypt()` 调用所传入的值相匹配。

* 使用 RSA-OAEP，则传入 `RsaOaepParams` (en-US) 对象。
* 使用 AES-CTR，则传入 `AesCtrParams` (en-US) 对象。
* 使用 AES-CBC，则传入 `AesCbcParams` (en-US) 对象。
* 使用 AES-GCM，则传入 `AesGcmParams` (en-US) 对象。

`key`

一个包含了密钥的 `CryptoKey` 对象，用于解密。

`data`

一个包含了待解密的数据（也称为密文）的 `ArrayBuffer`、`TypedArray` 或 `DataView` 对象。

### 返回值

一个 `Promise`，会兑现一个包含明文的 `ArrayBuffer`。

### 异常

当遇到以下异常时，promise 将会被拒绝：

`InvalidAccessError` `DOMException`

当提供的密钥无法执行请求的操作时（如：解密算法无效，或对指定的解密算法提供了无效的密钥）。

`OperationError` `DOMException`

因特定的操作原因导致操作失败时（如：算法的参数大小无效，或解密密文时发生的错误）。

支持的算法
-----

`decrypt()` 方法支持的算法与 `encrypt()` 方法所支持的相同。

示例
--

**备注：** 你可以在 GitHub 上尝试这个可用的示例。

### RSA-OAEP

以下代码使用 RSA-OAEP 解密 `ciphertext`。在 GitHub 中查看完整的代码。


```js
function decryptMessage(privateKey, ciphertext) {
  return window.crypto.subtle.decrypt(
    { name: "RSA-OAEP" },
    privateKey,
    ciphertext,
  );
}
```

### AES-CTR

以下代码使用计数器（CTR）模式的 AES 解密 `ciphertext`。请注意，`counter` 必须与加密时使用的值相匹配。在 GitHub 中查看完整的代码。


```js
function decryptMessage(key, ciphertext) {
  return window.crypto.subtle.decrypt(
    { name: "AES-CTR", counter, length: 64 },
    key,
    ciphertext,
  );
}
```

### AES-CBC

以下代码使用密码块链接（CBC）模式的 AES 解密 `ciphertext`。请注意，`iv` 必须与加密时使用的值相匹配。在 GitHub 中查看完整的代码。


```js
function decryptMessage(key, ciphertext) {
  return window.crypto.subtle.decrypt({ name: "AES-CBC", iv }, key, ciphertext);
}
```

### AES-GCM

以下代码使用伽罗瓦/计数器（GCM）模式的 AES 解密 `ciphertext`。请注意，`iv` 必须与加密时使用的值相匹配。在 GitHub 中查看完整的代码。


```js
function decryptMessage(key, ciphertext) {
  return window.crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
}
```

规范
--

| Specification |
| --- |
| Web Cryptography API # SubtleCrypto-method-decrypt |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `SubtleCrypto.encrypt()`。
* RFC 3447 规定了 RSAOAEP。
* NIST SP800-38A 规定了 CTR 模式。
* NIST SP800-38A 规定了 CBC 模式。
* NIST SP800-38D 规定了 GCM 模式。
* FIPS 198-1 规定了 HMAC。