网络
介绍
🌐 Introduction
Playwright 提供了用于监控和修改浏览器网络流量(包括 HTTP 和 HTTPS)的 API。页面发出的任何请求,包括 XHR 和 fetch 请求,都可以被跟踪、修改和处理。
🌐 Playwright provides APIs to monitor and modify browser network traffic, both HTTP and HTTPS. Any requests that a page does, including XHRs and fetch requests, can be tracked, modified and handled.
模拟 API
🌐 Mock APIs
查看我们的API 模拟指南以了解更多相关信息
🌐 Check out our API mocking guide to learn more on how to
- 模拟 API 请求并且从不访问 API
- 执行 API 请求并修改响应
- 使用 HAR 文件来模拟网络请求。
HTTP 认证
🌐 HTTP Authentication
执行 HTTP 身份验证。
🌐 Perform HTTP Authentication.
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setHttpCredentials("bill", "pa55w0rd"));
Page page = context.newPage();
page.navigate("https://example.com");
HTTP 代理
🌐 HTTP Proxy
你可以配置页面通过 HTTP(S) 代理或 SOCKSv5 加载。代理可以为整个浏览器全局设置,也可以单独为每个浏览器上下文设置。
🌐 You can configure pages to load over the HTTP(S) proxy or SOCKSv5. Proxy can be either set globally for the entire browser, or for each browser context individually.
你可以选择为 HTTP(S) 代理指定用户名和密码,也可以指定要绕过 setProxy 的主机。
🌐 You can optionally specify username and password for HTTP(S) proxy, you can also specify hosts to bypass the setProxy for.
这是全局代理的示例:
🌐 Here is an example of a global proxy:
Browser browser = chromium.launch(new BrowserType.LaunchOptions()
.setProxy(new Proxy("http://myproxy.com:3128")
.setUsername("usr")
.setPassword("pwd")));
也可以按上下文指定它:
🌐 Its also possible to specify it per context:
Browser browser = chromium.launch();
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setProxy(new Proxy("http://myproxy.com:3128")));
网络事件
🌐 Network events
你可以监控所有的 [请求] 和 [响应]:
🌐 You can monitor all the Requests and 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() 等待网络响应:
🌐 Or wait for a network response after the button click with Page.waitForResponse():
// Use a glob URL pattern
Response response = page.waitForResponse("**/api/fetch_data", () -> {
page.getByText("Update").click();
});
变化
🌐 Variations
使用 Page.waitForResponse() 等待 Response
🌐 Wait for Responses with Page.waitForResponse()
// 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();
});
处理请求
🌐 Handle requests
page.route("**/api/fetch_data", route -> route.fulfill(new Route.FulfillOptions()
.setStatus(200)
.setBody(testData)));
page.navigate("https://example.com");
你可以通过处理 Playwright 脚本中的网络请求来模拟 API 端点。
🌐 You can mock API endpoints via handling the network requests in your Playwright script.
变化
🌐 Variations
使用 BrowserContext.route() 在整个浏览器上下文中设置路由,或使用 Page.route() 在页面中设置路由。它将应用于弹出窗口和打开的链接。
🌐 Set up route on the entire browser context with BrowserContext.route() or page with Page.route(). It will apply to popup windows and opened links.
browserContext.route("**/api/login", route -> route.fulfill(new Route.FulfillOptions()
.setStatus(200)
.setBody("accept")));
page.navigate("https://example.com");
修改请求
🌐 Modify requests
// 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 头。
🌐 You can continue requests with modifications. Example above removes an HTTP header from the outgoing requests.
中止请求
🌐 Abort requests
你可以使用 Page.route() 和 Route.abort() 来中止请求。
🌐 You can abort requests using Page.route() and 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();
});
修改响应
🌐 Modify responses
要修改响应,请使用 APIRequestContext 获取原始响应,然后将响应传递给 Route.fulfill()。你可以通过选项覆盖响应中的各个字段:
🌐 To modify a response use APIRequestContext to get the original response and then pass the response to Route.fulfill(). You can override individual fields on the response via options:
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 模式
🌐 Glob URL patterns
Playwright 在网络拦截方法中(如 Page.route() 或 Page.waitForResponse())使用简化的全局匹配模式进行 URL 匹配。这些模式支持基本的通配符:
🌐 Playwright uses simplified glob patterns for URL matching in network interception methods like Page.route() or Page.waitForResponse(). These patterns support basic wildcards:
- 星号:
- 单个
*匹配除/之外的任意字符 - 双重
**匹配包括/在内的任意字符
- 单个
- 问号
?只匹配问号?。如果你想匹配任意字符,请使用*。 - 大括号
{}可用于匹配由逗号分隔的选项列表, - 反斜杠
\可用于转义任何特殊字符(注意,如果要转义反斜杠本身,则写作\\)
示例:
🌐 Examples:
https://example.com/*.js匹配https://example.com/file.js但不匹配https://example.com/path/file.jshttps://example.com/?page=1匹配https://example.com/?page=1但不匹配https://example.com**/*.js同时匹配https://example.com/file.js和https://example.com/path/file.js**/*.{png,jpg,jpeg}匹配所有图片请求
重要说明:
🌐 Important notes:
- glob 模式必须匹配整个 URL,而不仅仅是其中的一部分。
- 使用 glob 进行 URL 匹配时,请考虑完整的 URL 结构,包括协议和路径分隔符。
- 对于更复杂的匹配要求,请考虑使用 [RegExp] 而不是 glob 模式。
WebSockets
Playwright 原生支持 WebSockets 的检查、模拟和修改。请参阅我们的 API 模拟指南 了解如何模拟 WebSockets。
🌐 Playwright supports WebSockets inspection, mocking and modifying out of the box. See our API mocking guide to learn how to mock WebSockets.
每次创建 WebSocket 时,都会触发 Page.onWebSocket(handler) 事件。该事件包含 WebSocket 实例,可用于进一步检查 WebSocket 帧:
🌐 Every time a WebSocket is created, the Page.onWebSocket(handler) event is fired. This event contains the WebSocket instance for further web socket frames inspection:
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"));
});
缺少网络事件和 Service Worker
🌐 Missing Network Events and Service Workers
Playwright 内置的 BrowserContext.route() 和 Page.route() 允许你的测试原生路由请求,并执行模拟和拦截。
🌐 Playwright's built-in BrowserContext.route() and Page.route() allow your tests to natively route requests and perform mocking and interception.
如果你使用 Playwright 的原生 BrowserContext.route() 和 Page.route(),并且发现网络事件缺失,请通过将 setServiceWorkers 设置为 'block' 来禁用服务工作者。
🌐 If you're using Playwright's native BrowserContext.route() and Page.route(), and it appears network events are missing, disable Service Workers by setting setServiceWorkers to 'block'.
可能是你正在使用像 Mock Service Worker (MSW) 这样的模拟工具。虽然这个工具开箱即用,可以模拟响应,但它会添加自己的 Service Worker 来接管网络请求,从而使这些请求对 BrowserContext.route() 和 Page.route() 不可见。如果你对网络测试和模拟都感兴趣,建议使用内置的 BrowserContext.route() 和 Page.route() 来进行 响应模拟。
🌐 It might be that you are using a mock tool such as Mock Service Worker (MSW). While this tool works out of the box for mocking responses, it adds its own Service Worker that takes over the network requests, hence making them invisible to BrowserContext.route() and Page.route(). If you are interested in both network testing and mocking, consider using built-in BrowserContext.route() and Page.route() for response mocking.