HTML5相关规范解读(三):其他web api

1,466 阅读22分钟

本系列会将html5相关规范及涉及到的技术逐一解读,以完善我们的知识体系,其分为三期(建议按顺序阅读),分别是


介绍

本期讨论的是除了html和dom提到的以外的web api,web api就是js核心(es262)之外,由宿主提供的接口,这里的宿主指的是浏览器,其他宿主,比如node.js或者electron,会在其他专题里讨论。

其中对于偏api使用而不需要进一步理解的只会给出参考链接,不会过多解释。

更多背景情况请参考本系列第一期

Infra

这里会讲其他规范依赖的一些概念,下面介绍时涉及到时就不重复,这里挑出一些讲一下,具体参考Infra

Primitive data types

1 Nulls

表示缺少一个值,可以和es262中的null互换

2 Booleans

true或false

3 Bytes

一个字节(byte)表示一个8位序列,用0x后面跟两个16进制表示,范围是0x00 to 0xFF,一个字节的值是后面的数字,比如0x40表示64. 一个ascii byte是一个 0x00 (NUL) to 0x7F (DEL)范围的byte

4 byte sequences

一个字节序(byte sequences)是一个byte序列,用空格分隔的byte表示,范围是0x20 (SP) to 0x7E (~),可以写成字符串,但要用backticks而不是quotation

0x48 0x49可以表示为`HI`

5 Code points

一个代码点(code point)是一个unicode code point,用U+后面跟着四到六个大写16进制,范围是 U+0000 to U+10FFFF,一个码点的值是后面的数字。比如🤔的码点是U+1F914。
码点有时候用0x前缀,而不是U+ 一个surrogate是一个U+D800 to U+DFFF范围的码点。
一个scalar value是一个非surrogate码点。

6 Strings

字符串是一个无符号16位整数序列,也叫做code unit

Compatibility

有很多css(比如带webkit前缀)和dom api虽然不是标准用法,但是已经被广泛使用,因此浏览器也需要给予支持。详情参考原文

Console

console是个namespace,上面挂载了很多用于debug的工具方法

[Exposed=(Window,Worker,Worklet)]
namespace console { // but see namespace object requirements below
  // Logging
  undefined assert(optional boolean condition = false, any... data);
  undefined clear();
  undefined debug(any... data);
  undefined error(any... data);
  undefined info(any... data);
  undefined log(any... data);
  undefined table(optional any tabularData, optional sequence<DOMString> properties);
  undefined trace(any... data);
  undefined warn(any... data);
  undefined dir(optional any item, optional object? options);
  undefined dirxml(any... data);

  // Counting
  undefined count(optional DOMString label = "default");
  undefined countReset(optional DOMString label = "default");

  // Grouping
  undefined group(any... data);
  undefined groupCollapsed(any... data);
  undefined groupEnd();

  // Timing
  undefined time(optional DOMString label = "default");
  undefined timeLog(optional DOMString label = "default", any... data);
  undefined timeEnd(optional DOMString label = "default");
};

具体使用参考mdn

Encoding

这部分定义了编码及其api,参考mdnw3c

1 编码方式

计算机只能处理数字,而计算机存储以byte为单位,一字节等于8bit。以ascii码为例,用0到127之内的数字表示所有字符,比如65代表A,一个字节(可以表示2^8=256种字符)保存一个字符。
而英语世界以外的字符,比如汉语,GB系列用两个字节(可以表示256*256=65536中字符)表示大部分字符。
不同的编码在使用时需要分别处理,因此需要一种通用编码,即unicode,其中主要有三种标准,分别为utf-8,utf-16,utf-32,分别用无符号8位整数、16位无符号整数、32位无符号整数表示。比如汉字对应的数字是0x6c49和0x5b57,而编码的程序数据是

char      data_utf8[]={0xE6,0xB1,0x89,0xE5,0xAD,0x97};//UTF-8编码
char16_t data_utf16[]={0x6C49,0x5B57};        //UTF-16编码
char32_t data_utf32[]={0x00006C49,0x00005B57};//UTF-32编码

1.1 utf-8

utf-8以8位为单位进行编码,分为以下四组

范围utf-8
000000-00007F0xxxxxxx
000080-0007FF110xxxxx 10xxxxxx
000800-00FFFF1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

不同范围的字符使用不同长度的编码,比如第一组0x00-0x7F,与ascii码完全一样。最大长度是4子节,可以容纳21位二进制(x的数目)。
比如“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

再比如Unicode编码0x20C30在0x010000-0x10FFFF之间,使用4字节模板:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。将0x20C30写成21位二进制数字(不足21位就在前面补0):0 0010 0000 1100 0011 0000,用这个比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。

现在utf-8是最通用的编码,以前定义的一些遗留格式,不同用户代理处理起来会有差别,本规范会解决这些差距,因此用户代理并不需要去做兼容,而且还定义了所有编码。并将其部分算法以api的形式暴露给js。

1.2 BOM

utf-16和utf-32每个单位是用多个子节表示的,当多个字节表示一个单位时需要指定高位在前(大端字节序)还是低位在前(小端字节序),指定这个性质的就是BOM(byte order mark)。
对于utf-8,每个单位本身就是一个字节,本来不存在bom的问题,但是在具体实现中仍然存在有无BOM的问题

1.3 统一编码好处

  • 安全 一种编码的合法字段可能对于另一种编码是有危害的
  • 防止信息丢失

2 相关api

提供了两组编解码api用来处理不同字符编码

2.1 TextEncoder

输入码点输出utf-8子节,即编码

2.1.1 实例属性

  • encoding 编码器使用的编码算法名,只能返回utf-8

2.1.2 实例方法

  • encode(string) 返回一个Uint8Array对象包含编码后的utf-8
const encoder = new TextEncoder()
const view = encoder.encode('€')
console.log(view); // Uint8Array(3) [226, 130, 172]
  • encodeInto(string, uint8Array); 将编码后的utf-8放入指定uint8Array

2.2 TextDecoder

输入一个特定编码的文本,比如UTF-8, ISO-8859-2, KOI8-R, GBK等,输出码点,即解码.
这里提一个每种编码有一个name,有一个或多个label

构造函数
decoder = new TextDecoder(utfLabel, options);

第一个参数是被解码的编码label,默认utf-8,第二个参数是选项对象,包含属性fatal表示解码出错时是否报错

实例属性
  • encoding 特定解码器的名字
  • fatal 错误模式是不是error
  • ignoreBOM 是不是忽略 BOM
实例方法

对给定的参数进行解码

b1 = decoder.decode(buffer, options);
b2 = decoder.decode(buffer);
b3 = decoder.decode();

其中buffer指ArrayBuffer或包含文本的ArrayBufferView,options包含stream属性

let win1251decoder = new TextDecoder('windows-1251');
let bytes = new Uint8Array([207, 240, 232, 226, 229, 242, 44, 32, 236, 232, 240, 33]);
console.log(win1251decoder.decode(bytes)); // Привет, мир!

2.3 TextEncoderStream/TextDecoderStream

另一种编解码api

Fetch

这个标准定义了request,response和fetching的过程。

1 前言

一般来说fetching一个资源是很简单的操作,发一个请求,获得一个响应。但是这个操作的细节是很复杂的。
很多api都提供了fetch资源的能力,比如html的 img and script元素,css的cursor和list-style-image,js的navigator.sendBeacon()和self.importScripts()。fetch标准为这些特性提供了统一架构,因此涉及到各个方面是应该是一致的,比如重定向和CORS协议。
本标准还定义了一个fetch api,暴露了大部分底层网络功能,这也是本文的重点。

2 Infrastructure

2.1 URL

一个local scheme 是 "about", "blob", or "data" scheme,如果一个url的scheme是local scheme,那么就是local。
一个http(s) scheme 是"http" or "https" scheme
一个network scheme是ftp或http(s) scheme
一个fetch scheme是 "about", "blob", "data", "file"或network scheme。

参考URL部分

2.2 http

参考mdn,会在另外的文章详细讲解。

3 Fetch API

是获取资源的一个相对底层的api,比XHR更广泛一点,但是当前没有请求和响应进度。
比如 如果你想直接获得一个资源 然后将内容作为blob使用,可以

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => res.blob()).then(playBlob)

如果你只关心特定的header

fetch("/", {method:"HEAD"})
  .then(res => log(res.headers.get("strict-transport-security")))

如果你想处理query参数

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

如果你想逐渐接收body数据

function consume(reader) {
  var total = 0
  return pump()
  function pump() {
    return reader.read().then(({done, value}) => {
      if (done) {
        return
      }
      total += value.byteLength
      log(`received ${value.byteLength} bytes (${total} bytes in total)`)
      return pump()
    })
  }
}

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => consume(res.body.getReader()))
  .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
  .catch(e => log("something went wrong: " + e))

Fetch的核心在于对http相关接口分拆成多个模块,再加上WindowOrWorkerGlobalScope上的fetch方法,就成了当前使用的api

3.1 WindowOrWorkerGlobalScope.fetch()

fetch方法位于mixin WorkerOrGlobalScope,用于发起获取资源的请求,返回promise,当遇到网络错误或者权限等问题时会reject,否则都会resolve,其中包括404等情况,因此一个成功的fetch不仅要resolve还要检查Response为true.

该方法的参数和Request构造函数一样,会在Request部分详细讲解

3.2 Headers

用来创建header对象,对http header进行操作,可用header参考HTTP headers,出于安全考虑,其中forbidden request header namesforbidden response header names某些情况只能由浏览器控制。
每个header对象有一个关联的guard,取值immutable, request, request-no-cors, response, or none,会影响header的修改方法是否可以使用,具体取值取决于header在哪里使用

  • none 当使用Headers构造函数时,默认。
  • request 用在Request构造函数且没有mode:'no-cors'时,可以修改那些不是forbidden request header names的header
  • request-no-cors 用在Request构造函数且mode:'no-cors',此时可以修改CORS-safelisted request header
  • response 用在Response构造函数,可以修改不是forbidden response header names的header
  • immutable 用在Response的 error() or redirect() 方法,所有header都不可以修改
3.2.1 构造函数
var myHeaders = new Headers(init);

其中init是一个表示header的键值对对象或者另一个Headers对象

3.2.2 方法
  • Headers.append() 添加
  • Headers.delete() 删除
  • Headers.entries() 迭代
  • Headers.forEach()
  • Headers.get() 读取
  • Headers.has()
  • Headers.keys()
  • Headers.set()
  • Headers.values()

比如

var myHeaders = new Headers();

myHeaders.append('Content-Type', 'text/xml');
myHeaders.get('Content-Type') // should return 'text/xml'

3.3 Body

Body mixin 表示请求和相应的body,被Request和Response实现。

3.3.1 属性
  • Body.body 是一个ReadableStream对象(见Streams部分)
  • Body.bodyUsed 一个布尔值,表示body是不是使用过
3.3.2 方法

以下方法接收一个响应流,并返回一个携带对应类型的Promise

  • Body.arrayBuffer()
  • Body.blob()
  • Body.formData()
  • Body.json()
  • Body.text()

3.4 Request

表示一个请求

3.4.1 构造函数
var myRequest = new Request(input[, init]);

其中input用来定义要获取的资源,可以是

  • 一个字符串包含url
  • 一个Request对象,使用时会有一些变动
    • 如果这个对象存在于另一个origin,则Request.referrer会被去掉
    • 如果mode:navigate,mode会变为same-origin init具体为以下(参考Fetch规范,比mdn多一些参数):
dictionary RequestInit {
  ByteString method; 
  HeadersInit headers; 
  BodyInit? body;
  USVString referrer;
  ReferrerPolicy referrerPolicy;
  RequestMode mode;
  RequestCredentials credentials;
  RequestCache cache;
  RequestRedirect redirect;
  DOMString integrity;
  boolean keepalive;
  AbortSignal? signal;
  any window; // can only be set to null
};

enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style",  "track", "video", "worker", "xslt" };
enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
enum RequestRedirect { "follow", "error", "manual" };

注意credentials影响是否发送cookie,其中omit表示不发送,same-origin表示同域发送,include表示都发送,默认same-origin

3.4.2 属性

用来访问各种参数

3.4.3 方法

除了body上的方法,还有

  • Request.clone()

3.5 Response

表示一个响应

3.5.1 构造函数
var myResponse = new Response(body, init);

其中body默认为null,或者以下类型的值

  • Blob
  • BufferSource
  • FormData
  • ReadableStream
  • URLSearchParams
  • 字符串

其中init是一个对象可选以下对象

  • status
  • statusText
  • headers
3.5.2 属性
  • Response.headers
  • Response.ok 表示请求是否成功,即status在200-299
  • Response.redirected 是不是重定向
  • Response.status 响应码
  • Response.statusText 响应说明文字
  • Response.type
  • Response.url
  • Response.useFinalURL
3.5.3 方法
  • Response.clone()
  • Response.error()
  • Response.redirect()

Fullscreen

定义了一个api用于使元素全屏,使用Element.requestFullscreen()将特定元素全屏,使用Document.exitFullscreen()关闭全屏。
另外全屏的各个状态还有各种事件,比如fullscreenchange或fullscreenerror。

MIME Sniffing

http Content-Type header用来表示一个http响应的mine type,但是服务器提供的这个header不一定和实际内容匹配。之前web浏览器不得不通过除了这个header判断以外还要检查内容。但是具体怎么检查(sniff)并没有标准,因此不同浏览器的实现并不一样,而这会带来潜在的风险。

因此本规范就是介绍了这么一种内容嗅探(content sniffing)的算法。

Notifications

定义了一个api用于展示对终端用户的通知,特别是在浏览器视口外。
Notification构造函数用于完成这个功能。使用之前先调用Notification.requestPermission请求权限,如果同意再实例化Notification创建通知完成接下来的交互。参考Using the Notifications API

Quirks Mode

为了向下兼容引入了quirks mode。
浏览器的排版引擎支持三种模式

Storage

定义了持久化存储和配额(可以用多少空间以及用了多少)计算,以及平台存储架构。

用户代理包含多种半持久状态:

  • Credentials:凭证,比如用户名、密码通过表单提交
  • Permissions:权限,比如geolocation
  • Network:网络,比如HTTP cache, cookies, authentication entries, TLS client certificates
  • storage:存储,比如 Indexed DB, Cache API, service worker registrations, localStorage, sessionStorage, application caches(废弃), notifications, etc.

本规范主要讨论storage

1 Site storage units

每个origin的站点存储系统包含多个单一的站点存储单元(site storage unit),每个web站点或web应用都有自己的存储单元来放置数据,下图展示了一个站点的存储池中的三个存储单元

  • origin 1 由一些web storage和indexDB,也有一些空余,当前使用量并没有达到配额
  • origin 2 没存东西
  • origin 3 存满了,如果不删除就不能继续存。

用户代理会用各种技术决定不同origin的配额,最有可能的,也是规范鼓励的方法是,考虑站点的流行程度或使用水平来决定配额,也可以提供一个界面自定义配额。

2 Box modes

每个站点存储单元的实际数据存储叫做box,box mode描述了数据的保留策略。一共有两种mode

  • "best-effort" 尽量保存数据,但因存储不足需要清理时不会警告用户
  • "persistent" 持久保存,如果存储不足,先清理best-effort的,然后清理persistent并通知用户

如果要改变origin 的box mode,需要使用persistent-storage(参考Permissions)获取权限。

3 Data persistence and clearing

如果站点有persistent-storage权限,可以使用StorageManager.persist()方法请求将box持久化

4 Quotas and usage estimates

使用navigator.storage.estimate()获取配额和已使用量

navigator.storage.estimate().then(estimate => {
  // estimate.quota is the estimated quota
  // estimate.usage is the estimated number of bytes used
});

Streams

提供了创建、组合和消费data stream的api,有效的映射到底层的i/o primitives。

1 Introduction

大量的web平台建立在streaming data之上,即data以增量形式被创建、处理和消费,而不需要将全部读进内存。本标准提供了一系列api用于stream的创建和交互,包括 readable streams, writable streams, and transform streams.
这些api可以有效映射底层的i/o primitives,包括在合适的时候对byte stream进行特殊处理。可以轻易将多个stream组合成pipe chains,或者可以直接通过readers或writers使用。最后,还可以自动提供backpressure和queue。 标准提供了基本stream primitives,web 平台其他部分可以用来暴露它们的streaming data。比如fetch使用ReadableStream实例暴露了Response body。更常见的是平台充满了流抽象等着用流表示:multimedia stream,file streams等。
web开发者也可以用这些api创建自己的stream.

2 Concepts and usage

stream将你希望通过网络接收的资源拆分成小块,然后按位处理。这也是浏览器接收用于显示web页面的资源时所做的事情:视频buffer和其他逐渐可用,有时候你可以看到图片随着加载逐渐显示。
但是之前对于js并不可用,如果你想处理一个资源,我们不得不完全下载下来。
在stream可用以后,一切都变了,只要原始数据在客户端可用,就可以使用js按位处理,而不需要生成buffer,string或blob.
也有其他好处,可以监测stream什么时候开始或结束,将stream链接在一起,处理错误或者取消,并对读取速度做出反应。

3 Stream interfaces

相关接口包括

  • Readable streams,可读流
  • Writable streams 可写流
  • Related stream APIs and operations,流的操作

更进一步使用可参考mdn

URL

这个标准定义了URL,domains,ip地址,application/x-www-form-urlencoded格式和它们的api。
在本文主要介绍两个api,即URL和URLSearchParams

1 URL

用来解析、构造、规范化和编码url

1.1 构造函数

const url = new URL(url [, base])

其中参数url表示一个相对或绝对路径的url字符串,如果是相对路径则需要第二个参数

1.2 静态方法

1.2.1 createObjectURL

生成一个表示参数中给定对象的url字符串,这个url的生命周期和所属document绑定

const objectURL = URL.createObjectURL(object)

参数可以是创建url的File对象,Blob对象或MediaSource。
当不需要该url对象时需要使用URL.revokeObjectURL()主动释放

1.2.2 revokeObjectURL
window.URL.revokeObjectURL(objectURL);

1.3 实例属性

  • hash
  • host
  • hostname
  • href
  • origin
  • password
  • pathname
  • port
  • protocol
  • search
  • searchParams 是一个URLSearchParams对象
  • username

1.3 实例方法

  • toString()
  • toJSON()

2 URLSearchParams

定义了一些方法处理url的查询字符串

  • URLSearchParams.append()
  • URLSearchParams.delete()
  • URLSearchParams.entries()
  • URLSearchParams.get()
  • URLSearchParams.getAll()
  • URLSearchParams.has()
  • URLSearchParams.keys()
  • URLSearchParams.set()
  • URLSearchParams.sort()
  • URLSearchParams.toString()
  • URLSearchParams.values()

XMLHttpRequest

为客户端定义了一个api,用来在客户端和服务器之间传输数据

1 Introduction

XMLHttpRequest对象是一个获取资源的api
比如用来获取一个xml文档并做一些事情

function processData(data) {
  // taking care of data
}

function handler() {
  if(this.status == 200 &&
    this.responseXML != null &&
    this.responseXML.getElementById('test').textContent) {
    // success!
    processData(this.responseXML.getElementById('test').textContent);
  } else {
    // something went wrong
    …
  }
}

var client = new XMLHttpRequest();
client.onload = handler;
client.open("GET", "unicorn.xml");
client.send();

或者仅想向服务器发送一些消息

function log(message) {
  var client = new XMLHttpRequest();
  client.open("POST", "/log");
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(message);

或者检查服务器文档的状态

function fetchStatus(address) {
  var client = new XMLHttpRequest();
  client.onload = function() {
    // in case of network errors this might not give reliable results
    returnStatus(this.status);
  }
  client.open("HEAD", address);
  client.send();
}

2 Interface XMLHttpRequest

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestEventTarget : EventTarget {
  // event handlers
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onload;
  attribute EventHandler ontimeout;
  attribute EventHandler onloadend;
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
};

enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  constructor();

  // event handler
  attribute EventHandler onreadystatechange;

  // states
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  undefined open(ByteString method, USVString url);
  undefined open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
  undefined setRequestHeader(ByteString name, ByteString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  [SameObject] readonly attribute XMLHttpRequestUpload upload;
  undefined send(optional (Document or XMLHttpRequestBodyInit)? body = null);
  undefined abort();

  // response
  readonly attribute USVString responseURL;
  readonly attribute unsigned short status;
  readonly attribute ByteString statusText;
  ByteString? getResponseHeader(ByteString name);
  ByteString getAllResponseHeaders();
  undefined overrideMimeType(DOMString mime);
           attribute XMLHttpRequestResponseType responseType;
  readonly attribute any response;
  readonly attribute USVString responseText;
  [Exposed=Window] readonly attribute Document? responseXML;
};

2.1 Constructors

client = new XMLHttpRequest()

实例化一个client对象

2.2 事件处理器

XMLHttpRequest继承了 XMLHttpRequestEventTarget上七个事件处理器属性,另外还有一个自身的onreadystatechange事件处理器

2.3 States

client.readyState返回client的state,包括以下值

  • 0 UNSENT 对象还没构建
  • 1 OPENED open方法成功调用,这个时候可以使用setRequestHeader()设置header,也可以使用send()发送请求
  • 2 HEADERS_RECEIVED 所有重定向和所有header都收到
  • 3 LOADING 正在接收响应体
  • 4 DONE 数据接收完毕或者失败

2.4 Request

  • client . open(method, url [, async = true [, username = null [, password = null]]]) 初始化一个请求
  • client . setRequestHeader(name, value) 设置header
  • client . timeout 读写超时时间,单位毫秒
  • client . withCredentials 读写跨域时是否带有授权信息
  • client . upload 返回一个XMLHttpRequestUpload对象,这个对象也实现了XMLHttpRequestEventTarget,因此可以使用其事件处理器获取进度
  • client . send([body = null]) 发送请求,如果请求方法是get或head,参数为null,其中body可以是
    • 序列化的Document
    • Blob, BufferSource, FormData, URLSearchParams, 或者 USVString 对象.
    • null
  • client . abort() 如果请求已发出,则终止请求,此时readystate为0,status为0

2.5 Response

除了responseType其他属性都是只读的

  • responseURL 序列化的url
  • status 状态码
  • statusText 状态描述
  • getResponseHeader() 获取header
  • getAllResponseHeaders() 获取所有header
  • client . responseType [ = value ] 设置返回值的类型,可选
    • ''或text,返回字符串
    • arraybuffer 返回ArrayBuffer
    • blob 返回blob对象
    • document 返回xml或html文档
    • json js对象
  • response 返回对象,其类型取决于responseType,responseType要在open之后,send之前调用。
  • client . overrideMimeType(mime) 覆盖浏览器返回的mine type
  • client . responseText
  • client . responseXML

2.6 事件概览

除了第一个是Event类型,其余的都是ProgressEvent类型

  • readystatechange 当readyState属性变化(除了重置为0)时触发
  • loadstart fetch开始
  • progress 传输数据时
  • abort 调用abort
  • error
  • load
  • timeout
  • loadend

3 Interface FormData

提供了一种表示表单数据键值对的构造方式可以通过xhr.send发送出去。如果是get请求,那就要用URLSearchParams


[Exposed=(Window,Worker)]
interface FormData {
  constructor(optional HTMLFormElement form);

  undefined append(USVString name, USVString value);
  undefined append(USVString name, Blob blobValue, optional USVString filename);
  undefined delete(USVString name);
  FormDataEntryValue? get(USVString name);
  sequence<FormDataEntryValue> getAll(USVString name);
  boolean has(USVString name);
  undefined set(USVString name, USVString value);
  undefined set(USVString name, Blob blobValue, optional USVString filename);
  iterable<USVString, FormDataEntryValue>;
};

4 Interface ProgressEvent

继承自Event,用来处理进度,比如上面介绍的多个事件都是该类型

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface ProgressEvent : Event {
  constructor(DOMString type, optional ProgressEventInit eventInitDict = {});

  readonly attribute boolean lengthComputable;
  readonly attribute unsigned long long loaded;
  readonly attribute unsigned long long total;
};

dictionary ProgressEventInit : EventInit {
  boolean lengthComputable = false;
  unsigned long long loaded = 0;
  unsigned long long total = 0;
};

File api

这个规范提供了一个api用于在web应用中表示file对象,并且在程序中选择文件和访问其中的数据,包括

  • 一个FileList接口,表示选择的文件列表
  • 一个Blob接口,表示不可变的二进制对象
  • 一个File接口,包含文件的一些只读信息
  • 一个FileReader接口,提供了读取File或Blob的方法和对应事件模型
  • 一个使用二进制数据的url scheme

在web应用中使用文件demo可以参考mdn

1 FileList

一个文件列表,可以来自input或拖拽

var file = document.getElementById('fileItem').files[0];

2 Blob

表示一个blob对象,其是一个类似文件、不可变的原始数据,可以作为text或binary data读取或者转化为ReadableStream。
File接口基于Blob

2.1 构造函数

var newBlob = new Blob(array, options);

用来创建一个blob对象

2.2 实例属性

  • Blob.prototype.size
  • Blob.prototype.type mine-type

2.3 实例方法

  • Blob.prototype.arrayBuffer()
  • Blob.prototype.slice()
  • Blob.prototype.stream()
  • Blob.prototype.text()

3 File

是一个特殊的Blob,可以作为Blob使用,可以来自input或者拖拽,另外还包含以下属性

  • File.lastModified
  • File.lastModifiedDate
  • File.name
  • File.size
  • File.type

4 FileReader

用于在web应用异步读取文件内容,使用File或Blob指定要读的对象,参考mdn

5 A URL for Blob and MediaSource reference

用于引用Blob和MediaSource的url,用URL.createObjectURL创建,详见前面URL部分

Geolocation API

定义了一个api用于访问宿主的地理信息,参考mdn

Canvas api

canvas api提供了一种使用js和html元素绘制图形的方式,可以用于动画,游戏,数据可视化,图片操作和实时视频处理.
这个api主要是处理2d图像,WebGL API也使用canvas绘制硬件加速的2d和3d图像 比如

<canvas id="canvas"></canvas>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);

具体参考mdn

WebGL api

WebGL (Web Graphics Library)可在任何兼容的Web浏览器中渲染高性能的交互式3D和2D图形,而无需使用插件。参考mdn

HTML Drag and Drop API

用户可以使用鼠标选择draggable的元素到一个droppable的元素上,然后松开鼠标放下元素。参考mdn

IndexedDB

用于存储大量的结构化数据,是一个 transactional database system(事务型数据库系统),参考mdn

Clipboard API

提供了读写剪切版的功能,需要通过Permissions api获取权限后才可使用,参考mdn

Permissions

提供了用于权限相关的api,需要权限获取的api,比如

  • Clipboard API
  • Notifications API
  • Push API

参考mdn

Page Visibility

用来监测文档的可见性,比如切换tab或最小化,比如在不可见状态下不更新内容。参考mdn

Service Worker

作为web应用程序、浏览器和网络之间的代理服务器,可以用来实现离线应用、拦截网络请求和基于网络是否可用进行适当的操作、更新来自服务器的资源,另外还可以推送通知和访问后台同步api。参考mdn

Push API

可以用来接收服务器的推送消息,具体实现时需要结合service worker,当服务器想要推送消息时先发送给service worker,然后再转发给客户端,参考mdn

Resize Observer API

用来监测元素小大变化的api,参考mdn

WebRTC

WebRTC (Web Real-Time Communication) 用于浏览器之间的实时通讯,不需要借助中间媒介,这个话题会在后续文章展开讲述,可以参考mdn先了解一下。

PWA

Progressive web apps (PWAs)使用了多种现代浏览器的技术可以使web应用接近原生应用的体验,具体参考mdn

Background Tasks API

主要介绍了requestIdleCallback方法,用于在用户代理空闲时执行任务,具体使用参考mdn

Long Tasks API

用来监测哪些任务超过了50ms,参考mdn

Media Source Extensions API

用于直接在浏览器上播放媒体文件。结合MES,可以使用js创建媒体文件并通过audio和video元素播放,会在后续文章WebRTC主题的文章详细讲述。


本期撒花完结