webRequest.onBeforeRequest

當請求即將發出且請求頭尚不可用時,會觸發此事件。如果您想取消或重定向請求,這是一個很好的監聽時機。

要取消或重定向請求,首先在 addListener()extraInfoSpec 陣列引數中包含 "blocking"。然後,在監聽器函式中,返回一個 BlockingResponse 物件,並設定相應的屬性。

  • 要取消請求,請包含一個值為 truecancel 屬性。
  • 要重定向請求,請包含一個 redirectUrl 屬性,其值設定為您要重定向到的 URL。

如果擴充套件程式想要將公共(例如 HTTPS)URL 重定向到擴充套件程式頁面,則擴充套件程式的 manifest.json 檔案必須包含一個 web_accessible_resources 鍵,其中列出擴充套件程式頁面的 URL。

當多個阻塞處理程式修改請求時,只有一組修改會生效。重定向和取消具有相同的優先順序。因此,如果您取消了一個請求,如果另一個阻塞處理程式重定向了該請求,您可能會再次看到具有相同 requestId 的另一個請求。

從 Firefox 52 開始,監聽器可以返回一個解析為 BlockingResponsePromise,而不是直接返回 BlockingResponse。這使得監聽器可以非同步處理請求。

如果您使用 "blocking",則您的 manifest.json 中必須具有 "webRequestBlocking" API 許可權

語法

js
browser.webRequest.onBeforeRequest.addListener(
  listener,             // function
  filter,               //  object
  extraInfoSpec         //  optional array of strings
)
browser.webRequest.onBeforeRequest.removeListener(listener)
browser.webRequest.onBeforeRequest.hasListener(listener)

事件有三個函式

addListener(listener, filter, extraInfoSpec)

向此事件新增監聽器。

removeListener(listener)

停止監聽此事件。listener 引數是要移除的監聽器。

hasListener(listener)

檢查 listener 是否已為此事件註冊。如果正在監聽,則返回 true,否則返回 false

addListener 語法

引數

監聽器

當此事件發生時呼叫的函式。該函式將傳遞此引數

details

object。有關請求的詳細資訊。有關更多資訊,請參閱 details 部分。

返回: webRequest.BlockingResponse。如果在 extraInfoSpec 引數中指定了 "blocking",則事件監聽器應返回一個 BlockingResponse 物件,並可以設定其 cancel 或其 redirectUrl 屬性。從 Firefox 52 開始,監聽器可以返回一個解析為 BlockingResponsePromise,而不是直接返回 BlockingResponse。這使得監聽器可以非同步處理請求。

filter

webRequest.RequestFilter。一個過濾器,限制傳送給此監聽器的事件。

extraInfoSpec 可選

string 陣列。事件的額外選項。您可以傳遞以下任何值

  • "blocking":使請求同步,以便您可以取消或重定向請求
  • "requestBody":將 requestBody 包含在傳遞給監聽器的 details 物件中

額外物件

details

cookieStoreId

string。如果請求來自上下文身份中開啟的標籤頁,則為上下文身份的 cookie 儲存 ID。有關更多資訊,請參閱使用上下文身份

documentUrl

string。資源將載入到的文件的 URL。例如,如果“https://example.com”上的網頁包含影像或 iframe,則影像或 iframe 的 documentUrl 將是“https://example.com”。對於頂級文件,documentUrl 未定義。

frameAncestors

array。包含幀層次結構中每個文件(直至頂級文件)的資訊。陣列中的第一個元素包含有關所請求文件的直接父級的資訊,最後一個元素包含有關頂級文件的資訊。如果載入實際上是針對頂級文件,則此陣列為空。

url

string。文件載入來源的 URL。

frameId

integer。文件的 frameIddetails.frameAncestors[0].frameIddetails.parentFrameId 相同。

frameId

integer。如果請求發生在主幀中,則為零;正值是請求發生所在子幀的 ID。如果載入了(子)幀的文件(typemain_framesub_frame),frameId 表示此幀的 ID,而不是外部幀的 ID。幀 ID 在一個標籤頁內是唯一的。

incognito

boolean。請求是否來自隱私瀏覽視窗。

method(方法)

string。標準 HTTP 方法:例如,“GET”或“POST”。

originUrl

string。觸發請求的資源的 URL。例如,如果“https://example.com”包含一個連結,並且使用者點選該連結,則生成請求的 originUrl 為“https://example.com”。

originUrl 通常但不總是與 documentUrl 相同。例如,如果一個頁面包含一個 iframe,並且 iframe 包含一個將新文件載入到 iframe 中的連結,則生成請求的 documentUrl 將是 iframe 的父文件,但 originUrl 將是包含連結的 iframe 中文件的 URL。

parentFrameId

integer。包含傳送請求的幀的父幀的 ID。如果沒有父幀,則設定為 -1。

proxyInfo

object。此屬性僅在請求透過代理時存在。它包含以下屬性:

主機

string。代理伺服器的主機名。

port

integer。代理伺服器的埠號。

type

string。代理伺服器的型別。以下之一:

  • "http":HTTP 代理(或 HTTPS 的 SSL CONNECT)
  • "https":透過 TLS 連線到代理的 HTTP 代理
  • "socks":SOCKS v5 代理
  • "socks4":SOCKS v4 代理
  • "direct":無代理
  • "unknown":未知代理
username

string。代理服務的使用者名稱。

proxyDNS

boolean。如果代理將根據提供的主機名執行域名解析,這意味著客戶端不應自行進行 DNS 查詢,則為 True。

failoverTimeout

integer。故障轉移超時(秒)。如果代理連線失敗,在此期間將不再使用該代理。

requestBody 可選

object。包含 HTTP 請求正文資料。僅當 extraInfoSpec 包含 "requestBody" 時才提供。

error 可選

string。如果在獲取請求正文資料時遇到任何錯誤,則會設定此項。

formData 可選

object。如果請求方法是 POST 且正文是 UTF-8 編碼為“multipart/form-data”或“application/x-www-form-urlencoded”的鍵值對序列,則存在此物件。

它是一個字典,其中每個鍵包含該鍵的所有值的列表。例如:{'key': ['value1', 'value2']}。如果資料是另一種媒體型別,或者格式錯誤,則該物件不存在。

raw 可選

webRequest.UploadData 陣列。如果請求方法是 PUT 或 POST,並且正文尚未在 formData 中解析,則此陣列包含未解析的請求正文元素。

requestId

string。請求的 ID。請求 ID 在瀏覽器會話中是唯一的,因此您可以使用它們來關聯與同一請求相關的不同事件。

tabId

integer。請求發生所在標籤頁的 ID。如果請求與標籤頁無關,則設定為 -1。

thirdParty

boolean。指示請求及其內容視窗層次結構是否是第三方。

timeStamp

number。此事件觸發的時間,以紀元以來的毫秒數表示。

type

webRequest.ResourceType。正在請求的資源型別:例如,“image”、“script”、“stylesheet”。

url

string。請求的目標。

urlClassification

object。如果請求被Firefox 跟蹤保護分類,則與請求關聯的跟蹤型別。這是一個包含以下屬性的物件:

firstParty

array 型別的 string。請求的第一方分類標誌。

thirdParty

array 型別的 string。請求或其視窗層次結構的第三方分類標誌。

分類標誌包括:

  • fingerprintingfingerprinting_content:表示請求涉及指紋識別(“發現指紋識別的來源”)。
    • fingerprinting 表示該域屬於指紋識別和跟蹤類別。此類域的示例包括希望將配置檔案與訪問使用者關聯的廣告商。
    • fingerprinting_content 表示該域屬於指紋識別類別但不屬於跟蹤類別。此類域的示例包括使用指紋識別技術識別訪問使用者以進行反欺詐目的的支付提供商。
  • cryptominingcryptomining_content:類似於指紋識別類別,但用於加密挖礦資源。
  • trackingtracking_adtracking_analyticstracking_socialtracking_content:表示請求涉及跟蹤。tracking 是任何通用跟蹤請求,adanalyticssocialcontent 字尾標識跟蹤器的型別。
  • emailtrackingemailtracking_content:表示請求涉及跟蹤電子郵件。
  • any_basic_tracking:一個元標誌,結合了跟蹤和指紋識別標誌,不包括 tracking_contentfingerprinting_content
  • any_strict_tracking:一個元標誌,結合了所有跟蹤和指紋識別標誌。
  • any_social_tracking:一個元標誌,結合了所有社交跟蹤標誌。

您可以在 disconnect.me 網站上找到有關跟蹤器型別的更多資訊。content 字尾表示跟蹤並提供內容的跟蹤器。阻止它們可以保護使用者,但也可能導致網站損壞或元素無法顯示。

使用 BlockingResponse 時的 DNS 解析順序

關於在 OnBeforeRequest 中使用 BlockingResponse 時的 DNS 解析:在 HTTP 通道中,帶有阻塞響應的 onBeforeRequest 確實發生在 DNS 解析之前,也發生在推測性連線之前。對於其他通道,推測性連線可能導致 DNS 請求發生在 onBeforeRequest 之前。這種順序不是擴充套件程式開發者應該依賴的,因為它可能因瀏覽器而異,也可能因瀏覽器版本而異,更不用說一個請求通道與另一個請求通道之間了。請參閱 Mozilla 開發者提供的關於 DNS 解析順序的 BugZilla 問題澄清

示例

此程式碼記錄與 <all_urls> 模式匹配的每個請求資源的 URL

js
function logURL(requestDetails) {
  console.log(`Loading: ${requestDetails.url}`);
}

browser.webRequest.onBeforeRequest.addListener(logURL, {
  urls: ["<all_urls>"],
});

此程式碼取消向“https://mdn.club.tw/”下的 URL 發出的圖片請求(要檢視效果,請訪問 MDN 上包含圖片的任何頁面,例如 webRequest

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.club.tw/*";

// cancel function returns an object
// which contains a property `cancel` set to `true`
function cancel(requestDetails) {
  console.log(`Canceling: ${requestDetails.url}`);
  return { cancel: true };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  cancel,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

此程式碼透過重定向替換所有向“https://mdn.club.tw/”下的 URL 發出的圖片網路請求(要檢視效果,請訪問 MDN 上包含圖片的任何頁面,例如 webRequest

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.club.tw/*";

// redirect function
// returns an object with a property `redirectURL`
// set to the new URL
function redirect(requestDetails) {
  console.log(`Redirecting: ${requestDetails.url}`);
  return {
    redirectUrl:
      "https://38.media.tumblr.com/tumblr_ldbj01lZiP1qe0eclo1_500.gif",
  };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirect,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

此程式碼與上一個示例完全相同,只是監聽器非同步處理請求。它返回一個 Promise,該 Promise 設定一個計時器,並在計時器到期時解析為重定向 URL

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.club.tw/*";

// URL we will redirect to
let redirectUrl =
  "https://38.media.tumblr.com/tumblr_ldbj01lZiP1qe0eclo1_500.gif";

// redirect function returns a Promise
// which is resolved with the redirect URL when a timer expires
function redirectAsync(requestDetails) {
  console.log(`Redirecting async: ${requestDetails.url}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ redirectUrl });
    }, 2000);
  });
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirectAsync,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

另一個示例,將所有圖片重定向到資料 URL

js
let pattern = "https://mdn.club.tw/*";

let image = `
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <rect style="stroke-width: 10; stroke: #666666;" width="100%" height="100%" fill="#d4d0c8" />
    <text transform="translate(0, 9)" x="50%" y="50%" width="100%" fill="#666666" height="100%" style="text-anchor: middle; font: bold 10pt 'Segoe UI', Arial, Helvetica, Sans-serif;">Blocked</text>
  </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

這是另一個版本

js
function randomColor() {
  return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}

const pattern = "https://mdn.club.tw/*";

let image = `
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <rect width="100%" height="100%" fill="${randomColor()}"/>
  </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

擴充套件程式示例

瀏覽器相容性

注意:此 API 基於 Chromium 的 chrome.webRequest API。本文件源自 Chromium 程式碼中的 web_request.json