概念和用法
- 可以被使用到更多地应用场景中:无论是service workers、Cache API、又或者是其他处理请求和响应的方式,甚至是任何一种需要你自己在程序中生成响应的方式。
- Cache 接口为缓存的 Request / Response 对象对提供存储机制
- 为有关联性的概念,例如CORS和HTTP原生头信息,提供一种新的定义,取代它们原来那种分离的定义。
- 在Window 和 WorkerGlobalScope接口上实现了这个方法。因此在几乎所有环境中都可以用这个方法获取到资源。
- WorkerGlobalScope 接口 是一个代表了任何 scope of worker的接口(属于worker的对象)
- 无论请求成功与否,它都返回一个 Promise 对象
- 可以通过 Request() 和 Response() 的构造函数直接创建请求和响应,但是我们不建议这么做。他们应该被用于创建其他 API 的结果(比如,service workers 中的 FetchEvent.respondWith)。
- 使用ServiceWorker技术时,页面的提取动作会在ServiceWorker作用域(ServiceWorkerGlobalScope)中触发fetch事件.(应该是请求动作)
- 使用ServiceWorkerGlobalScope.onfetch或addEventListener监听.该事件回调会注入FetchEvent参数.它携带了有关请求和结果响应的信息以及方法
- FetchEvent.respondWith() ,允许我们向受控页面提供任意响应.
中止 fetch
- 浏览器已经开始为AbortController 和AbortSignal 接口(也就是Abort API)添加实验性支持,允许像 Fetch 和 XHR 这样的操作在还未完成时被中止 。
————————————————————————————————————————
AbortController
- AbortController接口代表一个控制器对象,允许你在需要时中止一个或多个DOM请求。
- 使用AbortController.AbortController()构造函数创建一个新的AbortController对象。
- 使用AbortSignal 对象完成与DOM请求的通信。
构造函数
- AbortController.AbortController() 创建一个新的AbortController 对象实例。
属性
- AbortController.signal 返回一个AbortSignal对象实例,它可以用来 with/abort(具有/终止) 一个DOM请求。
方法
- AbortController.abort() 中止一个尚未完成的DOM请求。这能够中止fetch 请求,任何响应Body的消费者和流。
- 当abort() 被调用,fetch() promise rejects 一个 AbortError。
示例
var controller = new AbortController(); // 创建一个控制器
var signal = controller.signal; // 获取该控制得信号对象
var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', function() {
controller.abort(); // 通过控制器终止它得信号对象关联得一个或多个请求
console.log('Download aborted');
});
function fetchVideo() {
...
fetch(url, {signal}).then(function(response) { // fetch方法参数2多了一个选项signal,用来把信号对象绑定到对应得请求中去,才能实现控制器得控制
...
}).catch(function(e) {
reports.textContent = 'Download error: ' + e.message;
})
}
————————————————————————————————————————
AbortSignal
- AbortSignal 接口表示一个信号对象( signal object ),它允许您通过 AbortController 对象与DOM请求(如Fetch)进行通信并在需要时将其中止。(实际是AbortController通过它和请求关联,关联得请求才能被控制器操作)
属性
- AbortSignal接口还继承了其父接口EventTarget的属性。
- EventTarget是一个由可以接收事件的对象实现的接口,并且可以为它们创建侦听器。(一个类,具有addEventListener等和事件相关得方法)
- AbortSignal.aborted (只读)以 Boolean 表示与之通信的请求是否被终止(true)或未终止(false)。
事件处理
- AbortSignal.onabort 当 abort 事件触发时,即当信号正在与之通信的DOM请求被中止时调用。
方法
- AbortSignal接口从其父接口 EventTarget 继承方法。
————————————————————————————————————————
Fetch
- 位于 WorkerOrGlobalScope 这一个 mixin 中的 fetch() 方法用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。
- Response 对象:作为参数传入then函数中的回调函数
- Window 和 WorkerGlobalScope 都实现了 WorkerOrGlobalScope。 ——这意味着基本在任何场景下只要你想获取资源,都可以使用 位于 WorkerOrGlobalScope 中的 fetch() 方法。
- 当遇到网络错误时,fetch() 返回的 promise 会被 reject,并传回 TypeError(HTTP 404 状态并不被认为是网络错误。)
- fetch() 方法由 Content Security Policy 的 connect-src指令控制,而不是它请求的资源。
- Content Security Policy:HTTP 响应头允许站点管理者控制用户代理能够为指定的页面加载哪些资源。将帮助防止跨站脚本攻击(Cross-Site Script)(XSS)
- connect-src:限制能通过脚本接口加载的URL。
语法
Promise<Response> fetch(input[, init]);
参数
- input 定义要获取的资源。这可能是:
- 一个 USVString 字符串,包含要获取资源的 URL。
- USVString 对应 unicode 标量值的所有可能序列的集合。它通常仅用于执行文本处理的 API,需要一串 unicode 标量值才能进行操作。除了不允许不成对的代理代码(应该是代理码点)之外, USVString 等同于 DOMString 。
- DOMString 是一个UTF-16字符串。由于JavaScript已经使用了这样的字符串,所以DOMString 直接映射到 一个String。
- 一个 Request 对象
- init 一个配置项对象,包括所有对请求的设置。可选的参数有:
- method: 请求使用的方法,如 GET、POST。
- headers: 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
- ByteString is a UTF-8 String that corresponds to the set of all possible sequences of bytes. (bytestring是一个utf-8字符串,它对应于所有可能的字节序列集。)
- body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
- BufferSource 一个类型,包括ArrayBuffer和ArrayBufferView.
- ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。
- ArrayBufferView is a helper type representing any of the following JavaScript TypedArray types(多种类数组二进制数据类型)
- mode: 请求的模式,如 cors、 no-cors 或者 same-origin。
- cors:
- no-cors:
- same-origin:
- credentials: 请求的 credentials,如 omit、same-origin 或者 include。
- omit:确保浏览器不在请求中包含凭据
- same-origin:请求URL与调用脚本位于同一起源处时发送凭据
- include:让浏览器发送包含凭据的请求(即使是跨域源)
- cache: 请求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
- default:
- no-store:缓存不应存储有关客户端请求或服务器响应的任何内容?来源于浏览器缓存
- reload:
- no-cache:强制高速缓存将请求提交给原始服务器进行验证。?来源于浏览器缓存
- force-cache:
- only-if-cached:表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝?来源于浏览器缓存
- redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向,默认值).
- referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。
- no-referrer:表示 Referer: 头将不会被发送。来源于跳转方法
- client:
- 一个 URL:
- referrerPolicy: 指定HTTP头 referer 的值 no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url (和referrer有什么区别?)
- no-referrer:
- no-referrer-when-downgrade:表示当从使用HTTPS的页面导航到非 HTTPS 页面时不会发送 Referer: 头。来源于跳转方法
- origin:
- origin-when-cross-origin:表示导航到其它源将会限制为这种组合:主机 + 端口,而导航到相同的源将会只包含 referrer的路径。来源于跳转方法
- unsafe-url:表示 referrer将会包含源和路径(domain + path)(但是不包含密码或用户名的片段)。这种情况是不安全的,因为它可能会将安全的URLs数据泄露给不安全的源。来源于跳转方法
- integrity: 包括请求的 subresource integrity 值 ( 例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
- subresource integrity 资源的哈希编码,用于校验资源的完整性
返回值
- 一个 Promise,resolve 时回传 Response 对象。
例外(错误类型)
- AbortError:The request was aborted (using AbortController.abort()).(请求被终止,使用了 AbortController.abort())
- TypeError:Since Firefox 43, fetch() will throw a TypeError if the URL has credentials, such as http://user:password@example.com.(传入的URL包含凭据时抛出,例如
http://user:password@example.com
)
示例
- 把图片2进制对象转换为URL地址,供带有src属性的标签使用。
var myImage = document.querySelector('img');
var myRequest = new Request('flowers.jpg');
fetch(myRequest).then(function(response) {
return response.blob();
}).then(function(response) {
var objectURL = URL.createObjectURL(response); // `objectURL = blob:https://www.w3cschool.cn/93496b0c-601c-4675-8a25-c64df2d662df`
myImage.src = objectURL;
});
————————————————————————————————————————
- Headers 接口允许您对HTTP请求和响应头执行各种操作。
- 在该接口的所有方法中,标题名称由不区分大小写的字节序列匹配。?
- 出于安全考虑,某些头只能由用户代理控制。这些头信息包括
- 请求首部
- 禁止修改的消息首部包括以 Proxy- 和 Sec- 开头的消息首部,
- Accept-Charset:用来告知(服务器)客户端可以处理的字符集类型。
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
- Accept-Encoding:客户端能够理解的内容编码方式——通常是某种压缩算法——进行通知
Accept-Encoding: gzip,deflate
- Access-Control-Request-Headers:告知服务器,实际请求将携带的自定义请求首部字段
Access-Control-Request-Headers: X-PINGOTHER
- Access-Control-Request-Method:告知服务器,实际请求将使用的请求方法
- Connection:决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。
- Content-Length:一个实体消息首部,用来指明发送给接收方的消息主体的大小,即用十进制数字表示的八位元组的数目。
- Cookie
- Cookie2(已废弃)
- Date
- DNT:表明了用户对于网站追踪的偏好。
- Expect:一个请求消息头,包含一个期望条件,表示服务器只有在满足此期望条件的情况下才能妥善地处理请求。
- 规范中只规定了一个期望条件
Expect: 100-continue
通知接收方客户端要发送一个体积可能很大的消息体,期望收到状态码为100(代表能够处理)否则返回417(节省流量)
- Host:请求头指明了服务器的域名(对于虚拟主机来说),以及(可选的)服务器监听的TCP端口号。
- Keep-Alive:一个通用消息头,允许消息发送者暗示连接的状态,还可以用来设置超时时长和最大请求数。(最大请求数:一次链接可以包含多个请求)
- Origin:指示了请求来自于哪个站点。该字段仅指示服务器名称,并不包含任何路径信息
- Referer:包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。
- TE:请求型头部用来指定用户代理希望使用的传输编码类型。
TE: gzip
- Trailer:一个响应首部,允许发送方在分块发送的消息后面添加额外的元信息,这些元信息可能是随着消息主体的发送动态生成的,比如消息的完整性校验,消息的数字签名,或者消息经过处理之后的最终状态等。(实体的元信息?)
- Transfer-Encoding: 消息首部指明了将 entity(实体) 安全传递给用户所采用的编码形式。
Transfer-Encoding: gzip
(实体的编码方式?)
- Upgrade:客户机指定它支持哪些额外的通信协议,如果服务器发现它适合于切换协议(非MDN)
- Via:一个通用首部,是由代理服务器添加的,适用于正向和反向代理,在请求和响应首部中均可出现。这个消息首部可以用来追踪消息转发情况,防止循环请求,以及识别在请求或响应传递链中消息发送者对于协议的支持能力。?
- 响应头部
- 一个Headers对象都有一个关联的guard,它具有不可变的值,request,request-no-cors,response或none。 这会影响 set(), delete(), 和append() 方法 改变header.
- 当使用 Headers() constructor 创建一个新的 Headers 对象的时候,它的 guard 被设置成 none(默认值)。
- 当创建 Request 或 Response 对象的时候,它将拥有一个按照以下规则实现的与之关联的 Headers 对象。
- Request() 构造函数 guard 为 request
- Request() 构造函数 mode 设置成 no-cors 时 guard 为 request-no-cors
- Response() 构造函数 guard 为 response
- Response.error()/Response.redirect() guard 为 immutable
- Guard 是 Headers 对象的特性,基于不同的情况,它可以有以下取值:immutable、request、request-no-cors、response 或 none。
- none:可以修改(不包括禁止的首部)
- request:请求头部,可以修改(不包括禁止的首部)
- request-no-cors:请求头部,只允许修改简单请求包括的头部(简单请求的头部和可人为修改的 CORS 安全首部相同,参考https://www.cnblogs.com/qq3279338858/p/11053015.html)
- response:响应头部,可以修改(不包括禁止的首部)
- immutable:不允许修改Headers
- 可以通过 Request.headers 和 Response.headers 属性检索一个Headers对象
- 使用 Headers.Headers() 构造函数创建一个新的Headers 对象
- 一个实现了Headers 的对象可以直接用于 for...of 结构中, 而不是 entries(): for (var p of myHeaders) 等价于 for (var p of myHeaders.entries()).
- Object对象没有Symbol.iterator方法,即没有内置迭代器,所以不支持for of循环
- 如果您尝试传入名称不是有效的HTTP头名称的引用,则所有Headers方法都将引发 TypeError
构造函数
- Headers.Headers() 创建一个新的Headers对象.
方法
- Headers.append() 给现有的header添加一个值, 或者添加一个未存在的header并赋值.(新增)
- Headers.delete() 从Headers对象中删除指定header.
- Headers.entries() 以 迭代器 的形式返回Headers对象中所有的键值对.
- Headers.get() 以 ByteString 的形式从Headers对象中返回指定header的全部值.
- ByteString 是一个可以对应所有可能的字节序列的字符串。在JavaScript中,当返回时ByteString映射到一个 String ; 通常,它只被用与协议交互式进行字节和字符串的相互转换 ,例如HTTP协议。?
- Headers.has() 以布尔值的形式从Headers对象中返回是否存在指定的header.
- Headers.keys() 以迭代器的形式返回Headers对象中所有存在的header名.
- Headers.set() 替换现有的header的值, 或者添加一个未存在的header并赋值.(替换)
- Headers.values() 以迭代器的形式返回Headers对象中所有存在的header的值.
范例
let myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
myHeaders.get('Content-Type');
// should return 'text/xml'
————————————————————————————————————————
Body
- Body mixin(类) 代表响应/请求的正文,允许你声明其内容类型是什么以及应该如何处理。
- Body被Request 和Response实现,并为这些对象提供了
- 一个相关联的主体(字节流)
- 一个已使用的标志(最初未设置)
- 一个MIME类型(最初为空字节序列)。
属性(只读)
- Body.body 一个简单的getter用于暴露一个ReadableStream类型的主体内容。
- Body.bodyUsed 一个Boolean 值指示是否body已经被标记读取。
方法
- Body.arrayBuffer() 使Response挂起一个流操作并且在完成时读取其值,它返回一个Promise对象,其resolve参数类型是ArrayBuffer。此操作会将bodyUsed状态改为已使用(true)。
- ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。
- Body.blob() 使Response挂起一个流操作并且在完成时读取其值,它返回一个Promise对象,其resolve参数类型是Blob。此操作会将bodyUsed状态改为已使用(true)。
- Body.formData() 使Response挂起一个流操作并且在完成时读取其值,它返回一个Promise对象,其resolve参数类型是FormData表单。此操作会将bodyUsed状态改为已使用(true)。
- Body.json() 使Response挂起一个流操作并且在完成时读取其值,它返回一个Promise对象,其resolve参数类型是使用JSON解析body文本的结果。此操作会将bodyUsed状态改为已使用(true)。
- Body.text() 使Response挂起一个流操作并且在完成时读取其值,它返回一个Promise对象,其resolve参数类型是USVString(文本)。此操作会将bodyUsed状态改为已使用(true)。
范例
- 使用 Response.Response() 构造函数创建自定义的 Response 对象。
const response = new Response();
————————————————————————————————————————
ReadableStream
- 流操作API中的ReadableStream 接口呈现了一个可读取的二进制流操作。
- 流将你希望通过网络接收的资源拆分成小块,然后按位处理它。这正是浏览器在接收用于显示web页面的资源时做的事情——视频缓冲区和更多的内容可以逐渐播放,有时候随着内容的加载,你可以看到图像逐渐地显示。
- 但曾经这些对于JavaScript是不可用的。以前,如果我们想要处理某种资源(如视频、文本文件等),我们必须下载完整的文件,等待它反序列化成适当的格式,然后在完整地接收到所有的内容后再进行处理
构造函数
- ReadableStream() 创建并从给定的Handler(处理程序)返回一个可读流对象。
属性
- ReadableStream.locked locked返回这个可读流是否被一个读取器锁定。
方法
- ReadableStream.cancel() 取消读取一束流, 消耗方发出一个信号,表示对这束流失去兴趣. 可以提供一个参数表示其原因给到底层代码, 使得不在应用这束流。(解锁?)
- ReadableStream.getReader() 创建一个读取器并且锁定流到读取器上,其他的读取器不能再捕获它,直到它被释放。
- ReadableStream.pipeThrough() 提供一个链式方法用于管道化一个现有的流,通过一个变换流或其他的可写可读对。?
- ReadableStream.pipeTo() 将现有的可读流管道输出给一个给定的可写流WritableStream,并在输出成功时保证填充,或在发生错误时返回拒绝。
- ReadableStream.tee() 返回包含两个ReadableStream实例分支的数组,每个元素接收了相同的传输数据
使用例程
- fetch一个请求并不是立马返回请求的结果,而是返回这个请求已经被成功响应,需要的结果正在传输过程中。所以上文提到Body的方法都返回一个Promise对象,就是用来等待结果数据完全传输后进行处理,切换Promise状态。?
fetch("https://www.example.org/").then((response) => {
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
// 下面的函数处理每个数据块
function push() {
// "done"是一个布尔型,"value"是一个Unit8Array
reader.read().then(({ done, value }) => {
// 判断是否还有可读的数据?
if (done) {
// 告诉浏览器已经结束数据发送。
controller.close();
return;
}
// 取得数据并将它通过controller发送给浏览器。
controller.enqueue(value);
push();
});
};
push();
}
});
return new Response(stream, { headers: { "Content-Type": "text/html" } });
});
————————————————————————————————————————
Request(请求)
- 可以使用 Request.Request() 构造函数创建一个Request 对象
- 可能会遇到一个 Request 对象作为其它 API 的操作返回,比如 service worker 的FetchEvent.request。
构造器
- Request.Request() 创建一个新的 Request 对象。
属性(只读)
- Request.method 包含请求的方法 (GET, POST, 等.)
- Request.url 包含这个请求的URL
- Request.headers 包含请求相关的Headers对象。
- Request.referrer 包含请求的来源 (例如:client)。
- Request.referrerPolicy 包含请求来源的策略 (例如:no-referrer)。
- Request.mode 包含请求的模式 (例如: cors, no-cors, same-origin, navigate).
- Request.credentials 包含请求的证书(例如: omit, same-origin).
- Request.redirect 包含如何处理重定向模式,它可能是一个 follow ,error或者manual。
- Request.integrity 包含请求的子资源的完整性值 (例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
- Request.cache 包含请求的缓存模式 (例如: default, reload, no-cache).
- Request实现了Body, 所以它还具有以下属性可用:
- Body.body 一个简单getter用于曝光一个ReadableStream的主体内容.
- Body.bodyUsed 存储一个Boolean判断主体是否已经被用于一个响应中.
方法
- Request.clone() 创建当前request的副本。
- Request实现 Body, 因此它也有以下方法可用:(这些Body功能只能运行一次; 随后的调用将通过空strings/ ArrayBuffers解析.)
- Body.arrayBuffer() 返回解决一个ArrayBuffer表示的请求主体的promise.
- Body.blob()
- Body.formData()
- Body.json()
- Body.text()
示例
- 通过将Request对象作为参数传递给GlobalFetch.fetch()调用来获取此请求
const myRequest = new Request('http://localhost/flowers.jpg');
fetch(myRequest)
.then(response => response.blob())
.then(blob => {
myImage.src = URL.createObjectURL(blob);
});
————————————————————————————————————————
Response(响应)
- Response 接口呈现了对一次请求的响应数据
- 可以使用Response.Response() 构造函数来创建一个 Response 对象
- 其他的API操作返回了一个Response对象,例如一个service worker 的Fetchevent.respondWith,或者一个简单的 GlobalFetch.fetch()
构造函数
- Response.Response() 创建一个新的Response 对象.
属性(大部分只读)
- Response.headers 包含此Response所关联的Headers 对象.
- Response.ok 包含了一个布尔值来标示该 Response 成功(状态码的范围在200-299)
- Response.redirected 表示该Response是否来自一个重定向,如果是的话,它的URL列表将会有多个entry
- Response.status 包含Response的状态码 (例如 200 表示成功)
- Response.statusText 包含了与该Response状态码一致的状态信息 (例如, OK对应 200).
- Response.type 包含Response的类型 (例如, basic, cors).
- basic: 标准值, 同源响应, 带有所有的头部信息除了“Set-Cookie” 和 “Set-Cookie2″.
- cors: Response 接收到一个有效的跨域请求. 部分headers和body可以被访问.
- error: 网络错误. 没有有用的描述错误的信息。响应的状态为0,header为空且不可变。从 Response.error()中获得的响应的类型.
- opaque: 响应 “no-cors” 的跨域请求. 严重受限.
- Response.url 包含Response的URL.