全部產品
Search
文件中心

Edge Security Acceleration:Fetch API

更新時間:Dec 23, 2025

Fetch API是一種從邊緣節點擷取資料的方法。通過Fetch API,您可以使用HTTP或HTTPS協議從邊緣節點請求資料,並將資料返回給使用者。它類似於瀏覽器環境中的Fetch API,可以用於動態載入內容、與後端服務進行互動、實現A/B測試等情境。

Fetch API方法定義

Fetch是完全非同步線程,只要您不使用await,Fetch就不會阻塞指令碼執行。目前每次可以發起4個子請求。由於底層採用的是長串連,您無需擔心效能,也不用主動處理串連池。

Fetch可以進行HTTP或HTTPS請求,每一次redirect都算一次請求。每一個Fetch最多可以支援12次redirect

  • 方法定義

    fetch(arg, init),Fetch的詳細定義請參見MDN官方文檔WorkerOrGlobalScope.fetch()

  • 方法限制

    • 目前Fetch API只支援網域名稱,不支援IP地址。HTTP請求對應的連接埠為80,HTTPS請求對應的連接埠為443。

    • init參數內部的credentialsreferrerreferrerPolicycacheintegrity無任何意義。

    • redirect預設值為follow,即fetch時如果來源站點返回3xx會直接跟隨。如果不需要跟隨3xx,需將redirect設定為manual

    說明
    • 對瀏覽器內部的多種Fetch模式不做區分,例如CROS fetch,在CDN/DCDN/ESA上您可以Fetch任何來源站點。

    • 如果需要4個及以上的子請求時,請提交工單申請配額。

    • 請求URL的總長度不超過4 KB。

    • 函數通過Fetch擷取的gzip壓縮資源預設解壓。如不希望預設解壓內容,請參見下方Decompress章節添加manual參數。

  • 設定逾時時間

    • Timeout函數

      /**
       * 請求逾時控制實現
       *
       * @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

Fetch運行支援3xx跟隨,即3xx重新導向。3xx包含的status code有301、302、303、307和308。根據標準您可以指定以下三種行為。

  • {redirect: "manual"}:不跟隨3xx,您自己處理。

  • {redirect: "error"}:3xx直接報錯。

  • {redirect: "follow"}:(預設值)跟隨3xx,最多支援20次。

重新導向方案見下表。

狀態代碼

重新導向說明

301、302、303、308

要求方法改成GET,body被忽略。

307

只跟隨GET方法,其他方法會報錯。

說明

重新導向的地址來源於Location頭,Location必須出現,否則會報錯。

  • Location可以含有由一個英文逗號,分割的URL表單,但只有第一個會被使用,其他均被忽略。

  • Location可以含有絕對URL或者相對URL。

Decompress

Fetch允許您配置API的解壓縮模式,例如fetch("https://www.example.com",{decompress: "manual"})。Fetch的decompress參數有以下三種值:

  • manual:不解壓縮。如果Fetch的伺服器將壓縮後的資料發送回來,則在ER中會讀取到被壓縮的資料。

  • decompress(預設值):自動解壓縮。目前Fetch支援Gzip壓縮模式,ER會根據content-encoding頭自動偵測或者使用解壓縮。ER如果執行瞭解壓縮,會自動修改content-encoding的值。如果刪除了其中的Gzip項,為了防止透傳時出現錯誤,您可以在下面兩種方式中任選一種進行設定:

    • content-encoding:gzip表示可以被ER識別。

    • content-encoding:gzip, identity表示可以被ER識別。

    說明

    其他非Gzip的演算法,目前會報錯。

  • fallbackIdentity:類似decompress,如果無法識別壓縮,則預設不解壓縮。

重要

Fetch自動壓縮後如果回複中有content-length頭,不能隨意透傳content-length頭,因為此時content-length表示未被解壓縮前的字元大小,不再反映解壓縮完成後的資料大小。

content-length

如果您使用Fetch請求資料時設定了content-length,Fetch會採用content-length的編碼,同時會改變Fetch發送body的預設行為。如果您不設定content-length,Fetch會主動把body流的所有資料讀取出來並發送,發送使用chunk-encoding。

  • content-length設定

    • content-length為非負數:根據您設定的值從發送的body流讀取相應的位元組後發送,發送採用content-length。如果content-length為0,則不發送任何資料。

    • content-length為非法值:繼續使用chunk-encoding發送所有body的值。

  • 舉例說明

    Fetch會自動解壓縮內容,解壓縮後response的content-length仍然存在,該content-length表示未被解壓縮前的資料大小。如果您改動body後再使用Fetch需注意content-length,否則發送的內容可能會出錯。

    以下樣本中,假設用戶端發送了一個POST請求,且header中包含了content-length。當您使用Fetch進行請求時,由於body複用了用戶端request的header對象,會導致content-length的值和當前發送的body實際資料大小不一致。您透傳header時一定要關注body的實際大小是否發生改變。

    export default {
      fetch(request) {
        return handleRequest(request)
      }
    }
    async function handleRequest(request) {
      return fetch("http://www.example.com", {
        headers: request.headers,
        method: request.method,
        body: "SomeData"
      });
    }

Headers

  • 定義

    Headers的定義,請參見MDN官方文檔Headers

  • 限制

    header內部會記錄記憶體消耗,header對象可以儲存的最大header是8 KB。如果單個header對象超用,會觸發JS exception。

  • 黑名單

    header有黑名單,無法讀寫以下頭,如果您讀取會造成exception。

    • expect

    • te

    • trailer

    • upgrade

    • proxy-connection

    • connection

    • keep-alive

    • dnt

    • host

    • 其他內部頭

Request

  • 定義

    Request的定義,請參見MDN官方文檔Request

  • 限制

    Request對象的以下屬性沒有實現,在CDN/DCDN/ESA上下文中沒有意義。

    • context

    • credentials

    • destination

    • integrity

    • mode

    • referrer

    • referrerPolicy

    • cache

  • 常見使用

    • 獲得要求方法:request.method

    • 獲得請求url:request.url

    • 獲得要求標頭:request.headers

    • 獲得請求負載:request.body,body是一個ReadableStream對象。

    • 獲得JSON:await request.json()

    • 獲得表單資料:await request.formData()

    • 獲得UTF8字串:await request.text()

    Request介面是標準的擴充,既可以忽略body,又確保body可以讀完,且不會將記憶體讀入JavaScript虛擬機器,從而避免了GC造成的延時,確保請求流的body從底層的socket中全部讀出。對於await request.ignore(),如果您不需要讀取Fetch的body或者不感興趣,建議所有的Fetch請求都調用request.ignore,可以有效提高效能,因為運行時會自動把讀取完body的請求發送至串連池中供下次複用。

Response

  • 定義

    Response的定義,請參見MDN官方文檔Response

  • 限制

    Response對象的useFinalURLS和error屬性沒有實現,在CDN/DCDN/ESA上下文中沒有意義。

  • 常見使用

    • 獲得回複碼:response.status

    • 獲得回複reason phrase:response.statusText

    • 獲得回複頭:response.headers

    • 獲得回複URL:response.url,表示該回複是對應的URL發送的。

    • 獲得所有redirect的URL list,屬於非標準:response.urlList,類似Request對象實現了body mixin,使用類似方法您可以獲得body對象。

FormData

  • 定義

    FormData的定義,請參見MDN官方文檔FormData

  • 限制

    FormData類似Header,有內部大小限制,如果過大FormData會出現異常。如果把FormData當作HTTP body發送,預設的content-typeform-data/multipart

URLSearchParams

  • 定義

    URLSearchParams的定義,請參見MDN官方文檔URLSearchParams()

  • 限制

    如果把URLSearchParams當作HTTPbody發送,預設的content-typeapplication/x-www-form-urlencode,最大限制為1000位元組。

Blob和File

  • 定義

    • Blob的定義,請參見MDN官方文檔Blob

    • File的定義,請參見MDN官方文檔File

  • 限制

    為了與標準保持一致,ER提供了Blob和File這兩個類。由於ER不支援讀寫檔案,為了滿足標準,您可以使用這兩個類,如果使用這兩個類提供給回複的body,content-typeBlobFile設定的mime type,和標準一致。