Fetch API是一种从边缘节点获取数据的方法。通过Fetch API,您可以使用HTTP或HTTPS协议从边缘节点请求数据,并将数据返回给用户。它类似于浏览器环境中的Fetch API,可以用于动态加载内容、与后端服务进行交互、实现A/B测试等场景。
Fetch是完全异步的线程,只要您不使用await,Fetch就不会阻塞脚本执行。目前每次可以发起4个子请求。由于底层采用的是长连接,您无需担心性能,也不用主动处理连接池。
Fetch可以进行HTTP或HTTPS请求,每一次redirect都算一次请求。每一个Fetch最多可以支持12次redirect。
fetch(arg, init) ,Fetch的详细定义请参见MDN官方文档 WorkerOrGlobalScope.fetch() 。
fetch(arg, init)
CROS fetch
manual
/** * 请求超时控制实现 * @param {Number} timeout 超时等待时间,单位ms * @param {Object} config 超时配置 * - @param {Object|Funtion} handler 超时返回 * @returns const RequestTimeout = (timeout, config) => { return new Promise((resolve) => { const { handler = null } = config; let timer = setTimeout(() => { clearTimeout(timer); timer = null; const defaultRes = (typeof handler === 'function' ? handler() : handler) || {}; resolve(defaultRes); }, timeout); };
const KV_TIMEOUT = 1000; let edgekv = new EdgeKV({ namespace: KV_NS, let kvRequest = edgekv.get(key, getType); let timeoutPromise = RequestTimeout(KV_TIMEOUT, { handler: { res: {}, errorMessage: `kv request timeout (${KV_TIMEOUT}ms)`, let resp = await Promise.race([ kvRequest, timeoutPromise, if (resp === undefined) { return "kv not found, key = " + key; } else { return resp; }
{redirect: "manual"}
{redirect: "error"}
{redirect: "follow"}
fetch("https://www.example.com",{decompress: "manual"})
content-encoding:gzip
content-encoding:gzip, identity
fetch("http://www.example.com", {cdnProxy: true})
Fetch会自动解压缩内容,解压缩后response的content-length仍然存在,该content-length表示未被解压缩前的数据大小。如果您改动body后再使用Fetch需注意content-length,否则发送的内容可能会出错。
addEventListener('fetch', (event) => { event.respondWith(h(event)); async function h(event) { return fetch("http://www.example.com", { headers: event.request.headers, method: event.request.method, body: "SomeData" }
Headers的定义,请参见MDN官方文档 Headers 。
header内部会记录内存消耗,header对象可以存储的最大header是8 KB。如果单个header对象超用,会触发JS exception。
Request的定义,请参见MDN官方文档 Request 。
request.method
request.url
request.headers
request.body
await request.json()
await request.formData()
await request.text()
Request接口是标准的扩充,既可以忽略body,又确保body可以读完,且不会将内存读入JavaScript虚拟机,从而避免了GC造成的延时,确保请求流的body从底层的socket中全部读出。对于 await request.ignore() ,如果您不需要读取Fetch的body或者不感兴趣,建议所有的Fetch请求都调用 request.ignore ,可以有效提高性能,因为运行时会自动把读取完body的请求发送至连接池中供下次复用。
await request.ignore()
request.ignore
Response的定义,请参见MDN官方文档 Response 。
Response对象的useFinalURLS和error属性没有实现,在CDN/DCDN上下文中没有意义。
response.status
response.statusText
response.headers
response.url
response.urlList
FormData的定义,请参见MDN官方文档 FormData 。
FormData类似Header,有内部大小限制,如果过大FormData会出现异常。如果把FormData当作HTTP body发送,默认的 content-type 是 form-data/multipart 。
content-type
form-data/multipart
URLSearchParams的定义,请参见MDN官方文档 URLSearchParams() 。
如果把URLSearchParams当作HTTPbody发送,默认的 content-type 是 application/x-www-form-urlencode ,最大限制为1000字节。
application/x-www-form-urlencode
为了与标准保持一致,ER提供了Blob和File这两个类。由于ER不支持读写文件,为了满足标准,您可以使用这两个类,如果使用这两个类提供给回复的body, content-type 是 Blob 和 File 设置的mime type,和标准一致。
Blob
File