You need to enable JavaScript to run this app.
导航
FetchEvent
最近更新时间:2024.06.26 20:11:04首次发布时间:2023.02.15 19:04:53

本文介绍 FetchEvent API 的使用方法和示例。关于其详细定义及用法,请参见 MDN 官方文档中的 FetchEvent

介绍

FetchEvent 包含了请求的信息,提供了一些方法,如 respondWithwaitUntil,使您能够控制请求的响应以及延长事件的生命周期。

  • 使用 respondWith 方法:可以控制对请求的响应,该方法接收一个应解析为 Response 对象的 Promise。
  • 使用 waitUntil 方法:可以延长事件的生命周期,直到传入的 Promise 对象完成(解析或拒绝)。

注意

边缘函数不支持直接构造 FetchEvent 。FetchEvent 是由系统生成的,当边缘函数监听到一个网络请求时,会触发 FetchEvent。您需要通过注册fetch监听器来响应FetchEvent

waitUntil方法

waitUntil 函数用于通知边缘函数等待所有该函数注册的 Promise 被处理完成后再回收请求上下文,从而延长事件处理的生命周期。默认情况下,请求上下文在处理完请求回复后会自动被回收。如果你的Promise没有使用 await 关键字,则存在在回收请求上下文前Promise尚未执行完成的风险。

注意

  • waitUntil中注册的 Promise 受运行时资源限制。
  • waitUntil可以调用多次,也可以waitUntil嵌套waitUntil。
  • waitUntil的默认行为是在所有注册的 Promise 中,如果有任何一个被拒绝,那么waitUntil依然会提前终止请求上下文,您可以通过包装 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事件过程中可能需要的数据处理工具。

Info

该函数用于在边缘接入层获取客户端信息。

常见用法

  • info.clientIp:客户端的IP地址。如果您的网络在边缘函数之前配置了代理,那么这个IP将是最近一次客户端请求的IP。如果没有配置代理,则是客户端自身的IP。
  • info.geo:客户端IP的地理信息。geo字段说明如下:
    • geo.country:表示该IP的国家,比如China
    • geo.countryCode:表示该IP的国家代码,比如CN
    • geo.region:表示该IP的区域
    • geo.province:表示该IP的省份
    • geo.city:表示该IP的城市
    • geo.isp:表示该IP的运营商

示例

addEventListener(
    'fetch', (event) => { event.respondWith(handle(event)); });
    
async function handle(event) {
  const info = event.info;
  console.log(info);  // 边缘接入层获得关于请求的相关信息
  return "done";
}

File/Blob

  • 详细定义及用法参见MDN官方文档File
  • 详细定义及用法参见MDN官方文档Blob

FormData

详细定义及用法参见MDN官方文档FormData