本文介绍 FetchEvent API 的使用方法和示例。关于其详细定义及用法,请参见 MDN 官方文档中的 FetchEvent。
FetchEvent 包含了请求的信息,提供了一些方法,如 respondWith
和 waitUntil
,使您能够控制请求的响应以及延长事件的生命周期。
respondWith
方法:可以控制对请求的响应,该方法接收一个应解析为 Response 对象的 Promise。waitUntil
方法:可以延长事件的生命周期,直到传入的 Promise 对象完成(解析或拒绝)。注意
边缘函数不支持直接构造 FetchEvent
。FetchEvent 是由系统生成的,当边缘函数监听到一个网络请求时,会触发 FetchEvent。您需要通过注册fetch监听器来响应FetchEvent
。
waitUntil 函数用于通知边缘函数等待所有该函数注册的 Promise 被处理完成后再回收请求上下文,从而延长事件处理的生命周期。默认情况下,请求上下文在处理完请求回复后会自动被回收。如果你的Promise没有使用 await 关键字,则存在在回收请求上下文前Promise尚未执行完成的风险。
注意
// 定义上传日志的URL const uploadURL = "https://log-collection.com/"; // 异步函数,用于上传回复的耗时 async function uploadLog(waiter) { const start = Date.now(); // 等待waiter promise结束,这表示请求的回复已经发送完成 await waiter; // 记录结束时间,注意,边缘函数的时钟与4ms对齐,这是为了规避side-channel attack const end = Date.now(); const cost = (end - start); await fetch(uploadURL, {method : "POST", body : {"cost" : ${cost}} }); } // 监听fetch事件,并在事件发生时,调用handle函数处理 addEventListener('fetch', (event) => { event.respondWith(handle(event)); }); // 处理事件的函数 async function handle(event) { const response = new Response("Hello World"); // response.body是一个readablestream,边缘函数的实现自带了waitClose函数 // waitClose返回一个promise,当stream被终止的时候(可能是因为出错或者读取完成),waitClose会被resolve // 注意:如果您的Response是用于返回HTTP HEAD/304/204等请求的时候,waitClose则没有作用,因为这些请求默认不会发送body部分 event.waitUntil(uploadLog(response.body.waitClose())); return response; }
Info函数提供了处理fetch事件过程中可能需要的客户端信息。File、Blob和FormData提供了处理fetch事件过程中可能需要的数据处理工具。
该函数用于在边缘接入层获取客户端信息。
addEventListener( 'fetch', (event) => { event.respondWith(handle(event)); }); async function handle(event) { const info = event.info; console.log(info); // 边缘接入层获得关于请求的相关信息 return "done"; }
详细定义及用法参见MDN官方文档FormData