Skip to main content

網路

簡介

Playwright 提供 API 來監控修改瀏覽器網路流量,包括 HTTP 和 HTTPS。頁面所做的任何請求,包括 XHRsfetch 請求,都可以被追蹤、修改和處理。

模擬 API

查看我們的 API mocking 指南 以了解更多資訊。

  • 模擬 API 請求並且不會觸發 API
  • 執行 API 請求並修改回應
  • 使用 HAR 檔案來模擬網路請求。

HTTP 認證

執行 HTTP 認證。

BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setHttpCredentials("bill", "pa55w0rd"));
Page page = context.newPage();
page.navigate("https://example.com");

HTTP Proxy

您可以配置頁面通過 HTTP(S) 代理或 SOCKSv5 加載。代理可以為整個瀏覽器全域設置,也可以為每個瀏覽器上下文單獨設置。

您可以選擇性地指定 HTTP(S) 代理的使用者名稱和密碼,也可以指定要略過 setProxy 的主機。

這裡是一個全域代理的範例:

Browser browser = chromium.launch(new BrowserType.LaunchOptions()
.setProxy(new Proxy("http://myproxy.com:3128")
.setUsername("usr")
.setPassword("pwd")));

也可以根據上下文指定它:

Browser browser = chromium.launch();
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setProxy(new Proxy("http://myproxy.com:3128")));

網路事件

你可以監控所有的 Requests 和 Responses:

import com.microsoft.playwright.*;

public class Example {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
BrowserType chromium = playwright.chromium();
Browser browser = chromium.launch();
Page page = browser.newPage();
page.onRequest(request -> System.out.println(">> " + request.method() + " " + request.url()));
page.onResponse(response -> System.out.println("<<" + response.status() + " " + response.url()));
page.navigate("https://example.com");
browser.close();
}
}
}

或者等待按鈕點擊後的網路回應,使用 Page.waitForResponse()

// Use a glob URL pattern
Response response = page.waitForResponse("**/api/fetch_data", () -> {
page.getByText("Update").click();
});

變體

使用 Page.waitForResponse() 等待 Response 回應

// Use a RegExp
Response response = page.waitForResponse(Pattern.compile("\\.jpeg$"), () -> {
page.getByText("Update").click();
});

// Use a predicate taking a Response object
Response response = page.waitForResponse(r -> r.url().contains(token), () -> {
page.getByText("Update").click();
});

處理請求

page.route("**/api/fetch_data", route -> route.fulfill(new Route.FulfillOptions()
.setStatus(200)
.setBody(testData)));
page.navigate("https://example.com");

您可以通過在您的 Playwright 腳本中處理網路請求來模擬 API 端點。

變體

在整個瀏覽器情境上使用 BrowserContext.route() 或頁面上使用 Page.route() 設定路由。這將適用於彈出視窗和開啟的連結。

browserContext.route("**/api/login", route -> route.fulfill(new Route.FulfillOptions()
.setStatus(200)
.setBody("accept")));
page.navigate("https://example.com");

修改請求

// Delete header
page.route("**/*", route -> {
Map<String, String> headers = new HashMap<>(route.request().headers());
headers.remove("X-Secret");
route.resume(new Route.ResumeOptions().setHeaders(headers));
});

// Continue requests as POST.
page.route("**/*", route -> route.resume(new Route.ResumeOptions().setMethod("POST")));

你可以繼續請求並進行修改。上面的範例從傳出的請求中移除了 HTTP 標頭。

中止請求

您可以使用 Page.route()Route.abort() 中止請求。

page.route("**/*.{png,jpg,jpeg}", route -> route.abort());

// Abort based on the request type
page.route("**/*", route -> {
if ("image".equals(route.request().resourceType()))
route.abort();
else
route.resume();
});

修改回應

使用 APIRequestContext 來修改回應,獲取原始回應,然後將回應傳遞給 Route.fulfill()。您可以透過選項覆寫回應中的個別欄位:

page.route("**/title.html", route -> {
// Fetch original response.
APIResponse response = route.fetch();
// Add a prefix to the title.
String body = response.text();
body = body.replace("<title>", "<title>My prefix:");
Map<String, String> headers = response.headers();
headers.put("content-type", "text/html");
route.fulfill(new Route.FulfillOptions()
// Pass all fields from the response.
.setResponse(response)
// Override response body.
.setBody(body)
// Force content type to be html.
.setHeaders(headers));
});

Glob URL 模式

Playwright 在網路攔截方法(如 Page.route()Page.waitForResponse())中使用簡化的 glob 模式進行 URL 比對。這些模式支援基本的萬用字元:

  1. 星號:
    • 單個 * 匹配除 / 以外的任何字元
    • 雙重 ** 匹配包括 / 在內的任何字元
  2. 問號 ? 只匹配問號 ?。如果你想匹配任何字元,請改用 *
  3. 大括號 {} 可用來匹配以逗號 , 分隔的選項清單
  4. 反斜線 \ 可用來跳脫任何特殊字元(注意將反斜線本身跳脫為 \\

範例:

  • https://example.com/*.js 匹配 https://example.com/file.js 但不匹配 https://example.com/path/file.js
  • https://example.com/?page=1 匹配 https://example.com/?page=1 但不匹配 https://example.com
  • **/*.js 同時匹配 https://example.com/file.jshttps://example.com/path/file.js
  • **/*.{png,jpg,jpeg} 匹配所有圖片請求

重要注意事項:

  • glob 模式必須匹配整個 URL,而不僅是其中一部分。
  • 使用 glob 進行 URL 匹配時,請考慮完整的 URL 結構,包括協定和路徑分隔符。
  • 對於更複雜的匹配需求,請考慮使用 [RegExp] 而不是 glob 模式。

WebSockets

Playwright 支援 WebSockets 檢查、模擬和修改的開箱即用功能。查看我們的 API mocking 指南 以了解如何模擬 WebSockets。

每次建立 WebSocket 時,會觸發 Page.onWebSocket(handler) 事件。此事件包含 WebSocket 實例以進一步檢查 web socket 幀:

page.onWebSocket(ws -> {
log("WebSocket opened: " + ws.url());
ws.onFrameSent(frameData -> log(frameData.text()));
ws.onFrameReceived(frameData -> log(frameData.text()));
ws.onClose(ws1 -> log("WebSocket closed"));
});

缺少網路事件和服務工作者

Playwright 的內建 BrowserContext.route()Page.route() 允許你的測試原生地路由請求並執行模擬和攔截。

  1. 如果您使用 Playwright 的原生 BrowserContext.route()Page.route(),並且發現缺少網路事件,請將 setServiceWorkers 設定為 'block' 來停用 Service Workers。
  2. 您可能正在使用諸如 Mock Service Worker (MSW) 之類的模擬工具。雖然此工具可以直接用於模擬回應,但它會新增自己的 Service Worker 來接管網路請求,因此使 BrowserContext.route()Page.route() 無法看到這些請求。如果您對網路測試和模擬都感興趣,請考慮使用內建的 BrowserContext.route()Page.route() 進行回應模擬
  3. 如果你不僅僅對使用 Service Workers 進行測試和網路模擬感興趣,還對路由和監聽由 Service Workers 自己發出的請求感興趣,請參閱這個實驗性功能