BrowserContext
浏览器上下文(BrowserContexts)提供了一种操作多个独立浏览器会话的方式。
如果一个页面打开了另一个页面(例如通过 window.open
调用),弹出的页面将属于父页面的浏览器上下文。
Playwright 允许通过 browser.newContext() 方法创建隔离的非持久化浏览器上下文。非持久化浏览器上下文不会向磁盘写入任何浏览数据。
// 创建一个新的无痕浏览器上下文
const context = await browser.newContext();
// 在该上下文中创建一个新页面
const page = await context.newPage();
await page.goto('https://example.com');
// 当不再需要时销毁上下文
await context.close();
方法
addCookies
v1.9 之前添加向此浏览器上下文中添加 cookies。该上下文中的所有页面都将安装这些 cookies。可以通过 browserContext.cookies() 获取 cookies。
用法
await browserContext.addCookies([cookieObject1, cookieObject2]);
参数
cookies
Array<Object>#-
name
string -
value
string -
url
string (可选)必须提供 url 或 domain/path。可选。
-
domain
string (可选)要使 cookie 适用于所有子域,请在域名前加上点,例如:".example.com"。必须提供 url 或 domain/path。可选。
-
path
string (可选)必须提供 url 或 domain/path。可选。
-
expires
number (可选)以秒为单位的 Unix 时间。可选。
-
httpOnly
boolean (可选)可选。
-
secure
boolean (可选)可选。
-
sameSite
"Strict" | "Lax" | "None" (可选)可选。
-
返回值
addInitScript
v1.9 之前添加添加一个脚本,该脚本会在以下任一场景中被执行:
- 当浏览器上下文中创建页面或导航时
- 当浏览器上下文中任何页面的子框架被附加或导航时。此时脚本会在新附加的框架上下文中执行
脚本会在文档创建后但执行其任何脚本前被评估。这对于修改 JavaScript 环境很有用,例如设置 Math.random
的种子值。
用法
在页面加载前覆盖 Math.random
的示例:
// preload.js
Math.random = () => 42;
// 在 Playwright 脚本中,假设 preload.js 文件位于同一目录
await browserContext.addInitScript({
path: 'preload.js'
});
:::注意 通过 browserContext.addInitScript() 和 page.addInitScript() 安装的多个脚本的执行顺序是不确定的。 :::
参数
-
script
function | string | Object#需要在浏览器上下文所有页面中评估的脚本。
-
arg
Serializable (可选)#传递给脚本的可选参数(仅在传递函数时支持)。
返回
backgroundPages
添加于: v1.11仅基于 Chromium 的浏览器支持后台页面。
返回该上下文中所有现有的后台页面。
用法
browserContext.backgroundPages();
返回值
browser
v1.9 之前添加返回该上下文的浏览器实例。如果是以持久化上下文启动的,则返回 null。
用法
browserContext.browser();
返回值
clearCookies
v1.9 之前添加清除上下文中的 cookies。可接受可选过滤器。
用法
await context.clearCookies();
await context.clearCookies({ name: 'session-id' });
await context.clearCookies({ domain: 'my-origin.com' });
await context.clearCookies({ domain: /.*my-origin\.com/ });
await context.clearCookies({ path: '/api/v1' });
await context.clearCookies({ name: 'session-id', domain: 'my-origin.com' });
参数
options
Object (可选)
返回
clearPermissions
Added before v1.9清除浏览器上下文的所有权限覆盖设置。
用法
const context = await browser.newContext();
await context.grantPermissions(['clipboard-read']);
// 执行操作..
context.clearPermissions();
返回值
close
Added before v1.9关闭浏览器上下文。属于该上下文的所有页面都将被关闭。
:::注意
默认浏览器上下文无法被关闭。 :::
用法
await browserContext.close();
await browserContext.close(options);
参数
返回值
cookies
v1.9 版本前添加如果不指定 URL,该方法会返回所有 cookies。如果指定了 URL,则只返回影响这些 URL 的 cookies。
用法
await browserContext.cookies();
await browserContext.cookies(urls);
参数
返回值
exposeBinding
v1.9 之前添加该方法在上下文中所有页面的每个框架的 window
对象上添加一个名为 name 的函数。当调用时,该函数会执行 callback 并返回一个 Promise,该 Promise 会解析为 callback 的返回值。如果 callback 返回一个 Promise,则会等待其完成。
callback 函数的第一个参数包含调用者的信息:{ browserContext: BrowserContext, page: Page, frame: Frame }
。
单页面版本请参见 page.exposeBinding()。
用法示例
以下示例展示如何将页面 URL 暴露给上下文中所有页面的所有框架:
const { webkit } = require('playwright'); // 或 'chromium' 或 'firefox'。
(async () => {
const browser = await webkit.launch({ headless: false });
const context = await browser.newContext();
await context.exposeBinding('pageURL', ({ page }) => page.url());
const page = await context.newPage();
await page.setContent(`
<script>
async function onClick() {
document.querySelector('div').textContent = await window.pageURL();
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
`);
await page.getByRole('button').click();
})();
参数
-
在 window 对象上注册的函数名。
-
在 Playwright 上下文中调用的回调函数。
-
options
Object (可选)
返回值
exposeFunction
v1.9 之前版本添加该方法会在上下文所有页面中每个 frame 的 window
对象上添加一个名为 name 的函数。当调用该函数时,会执行 callback 并返回一个 Promise,该 Promise 会解析为 callback 的返回值。
如果 callback 返回一个 Promise,则会等待其解析。
仅针对单个页面的版本请参见 page.exposeFunction()。
用法示例
以下是在上下文中所有页面上添加 sha256
函数的示例:
const { webkit } = require('playwright'); // 或 'chromium' 或 'firefox'
const crypto = require('crypto');
(async () => {
const browser = await webkit.launch({ headless: false });
const context = await browser.newContext();
await context.exposeFunction('sha256', text =>
crypto.createHash('sha256').update(text).digest('hex'),
);
const page = await context.newPage();
await page.setContent(`
<script>
async function onClick() {
document.querySelector('div').textContent = await window.sha256('PLAYWRIGHT');
}
</script>
<button onclick="onClick()">Click me</button>
<div></div>
`);
await page.getByRole('button').click();
})();
参数
返回值
grantPermissions
v1.9 之前添加向浏览器上下文授予指定权限。如果指定了来源,则仅授予该来源对应的权限。
用法
await browserContext.grantPermissions(permissions);
await browserContext.grantPermissions(permissions, options);
参数
-
要授予的权限列表。
危险不同浏览器支持的权限不同,甚至同一浏览器的不同版本之间也有差异。任何权限都可能在更新后失效。
以下是部分浏览器可能支持的一些权限:
'accelerometer'
'ambient-light-sensor'
'background-sync'
'camera'
'clipboard-read'
'clipboard-write'
'geolocation'
'gyroscope'
'magnetometer'
'microphone'
'midi-sysex'
(系统独占 MIDI)'midi'
'notifications'
'payment-handler'
'storage-access'
-
options
Object (可选)-
要授予权限的[来源],例如 "https://example.com"。
-
返回值
newCDPSession
Added in: v1.11CDP 会话仅支持基于 Chromium 的浏览器。
返回新创建的会话。
用法
await browserContext.newCDPSession(page);
参数
返回值
newPage
Added before v1.9在浏览器上下文中创建一个新页面。
用法
await browserContext.newPage();
返回值
pages
Added before v1.9返回上下文中所有打开的页面。
用法
browserContext.pages();
返回值
removeAllListeners
Added in: v1.47移除指定类型的所有监听器(如果不指定类型则移除所有已注册的监听器)。允许等待异步监听器完成或忽略这些监听器的后续错误。
用法
await browserContext.removeAllListeners();
await browserContext.removeAllListeners(type, options);
参数
type
string (可选)#options
Object (可选)-
behavior
"wait" | "ignoreErrors" | "default" (可选)#指定是否等待正在运行的监听器完成以及如何处理它们抛出的错误:
'default'
- 不等待当前监听器调用(如果有)完成,如果监听器抛出错误,可能会导致未处理的错误'wait'
- 等待当前监听器调用(如果有)完成'ignoreErrors'
- 不等待当前监听器调用(如果有)完成,移除后监听器抛出的所有错误将被静默捕获
-
返回值
route
v1.9 之前添加路由功能允许修改浏览器上下文中任何页面发出的网络请求。一旦启用路由,所有匹配 URL 模式的请求都会被挂起,除非该请求被继续执行、完成或中止。
:::注意
browserContext.route() 不会拦截被 Service Worker 拦截的请求。参见此问题。我们建议在使用请求拦截时,通过将 serviceWorkers 设置为 'block'
来禁用 Service Worker。
:::
用法
以下是一个简单处理器的示例,它会中止所有图片请求:
const context = await browser.newContext();
await context.route('**/*.{png,jpg,jpeg}', route => route.abort());
const page = await context.newPage();
await page.goto('https://example.com');
await browser.close();
或者使用正则表达式模式的相同代码片段:
const context = await browser.newContext();
await context.route(/(\.png$)|(\.jpg$)/, route => route.abort());
const page = await context.newPage();
await page.goto('https://example.com');
await browser.close();
可以检查请求来决定路由行为。例如,模拟所有包含特定 post 数据的请求,而其他请求保持不变:
await context.route('/api/**', async route => {
if (route.request().postData().includes('my-string'))
await route.fulfill({ body: 'mocked-data' });
else
await route.continue();
});
当请求同时匹配页面路由(通过 page.route() 设置)和浏览器上下文路由时,页面路由的优先级更高。
要移除路由及其处理器,可以使用 browserContext.unroute()。
:::注意
启用路由会禁用 HTTP 缓存。 :::
参数
-
url
string | RegExp | function(URL):boolean#用于路由匹配的 glob 模式、正则表达式模式或接收 URL 的谓词函数。如果在上下文选项中设置了 baseURL 且提供的 URL 是不以
*
开头的字符串,则会使用new URL()
构造函数解析。 -
handler
function(Route, Request):Promise<Object> | Object#用于路由请求的处理器函数。
-
options
Object (可选)
返回值
routeFromHAR
添加于: v1.23如果指定此方法,上下文中的网络请求将从 HAR 文件提供。了解更多关于 从 HAR 回放 的信息。
Playwright 不会从 HAR 文件提供被 Service Worker 拦截的请求。参见 此问题。我们建议在使用请求拦截时通过设置 serviceWorkers 为 'block'
来禁用 Service Workers。
用法
await browserContext.routeFromHAR(har);
await browserContext.routeFromHAR(har, options);
参数
-
包含预录制网络数据的 HAR 文件路径。如果
path
是相对路径,则相对于当前工作目录解析。 -
options
Object (可选)-
notFound
"abort" | "fallback" (可选)#- 如果设置为 'abort',任何在 HAR 文件中找不到的请求将被中止。
- 如果设置为 'fallback',则回退到处理链中的下一个路由处理器。
默认为 abort。
-
如果指定,将使用实际网络信息更新给定的 HAR 文件,而不是从文件提供。文件在调用 browserContext.close() 时写入磁盘。
-
updateContent
"embed" | "attach" (可选) 添加于: v1.32#控制资源内容管理的可选设置。如果指定
attach
,资源将作为单独的文件或 ZIP 存档中的条目持久化。如果指定embed
,内容将内联存储在 HAR 文件中。 -
updateMode
"full" | "minimal" (可选) 添加于: v1.32#当设置为
minimal
时,仅记录从 HAR 路由所需的信息。这会省略大小、计时、页面、cookies、安全性以及其他在从 HAR 回放时不使用的 HAR 信息类型。默认为minimal
。 -
用于匹配请求 URL 的通配符模式、正则表达式或谓词。只有 URL 匹配模式的请求才会从 HAR 文件提供。如果未指定,则所有请求都从 HAR 文件提供。
-
返回
routeWebSocket
添加于: v1.48此方法允许修改浏览器上下文中任何页面建立的 WebSocket 连接。
注意:只有在此方法调用后创建的 WebSocket
才会被路由。建议在创建任何页面之前调用此方法。
用法
下面是一个简单的处理程序示例,用于拦截某些 WebSocket 消息。更多详情和示例请参见 WebSocketRoute。
await context.routeWebSocket('/ws', async ws => {
ws.routeSend(message => {
if (message === 'to-be-blocked')
return;
ws.send(message);
});
await ws.connect();
});
参数
-
url
string | RegExp | function(URL):boolean#只有 URL 匹配此模式的 WebSocket 才会被路由。字符串模式可以相对于上下文选项 baseURL。
-
handler
function(WebSocketRoute):Promise<Object> | Object#用于路由 WebSocket 的处理函数。
返回值
serviceWorkers
v1.11 版本新增Service Worker 仅在基于 Chromium 的浏览器中支持。
返回当前上下文中所有已存在的 Service Worker。
用法
browserContext.serviceWorkers();
返回值
setDefaultNavigationTimeout
v1.9 之前版本已添加此设置将更改以下方法及其相关快捷操作的默认最大导航超时时间:
用法
browserContext.setDefaultNavigationTimeout(timeout);
参数
setDefaultTimeout
v1.9 版本前添加此设置将更改所有接受 timeout 选项的方法的默认最大超时时间。
:::注意 page.setDefaultNavigationTimeout()、page.setDefaultTimeout() 和 browserContext.setDefaultNavigationTimeout() 的优先级高于 browserContext.setDefaultTimeout()。 :::
用法
browserContext.setDefaultTimeout(timeout);
参数
setExtraHTTPHeaders
v1.9 版本前添加额外的 HTTP 头信息将会随该上下文中任何页面发起的每个请求一起发送。这些头信息会与通过 page.setExtraHTTPHeaders() 设置的页面特定额外 HTTP 头信息合并。如果页面覆盖了某个特定头信息,将使用页面特定的头信息值而非浏览器上下文中的头信息值。
:::注意
browserContext.setExtraHTTPHeaders() 不保证输出请求中头信息的顺序。 :::
用法
await browserContext.setExtraHTTPHeaders(headers);
参数
返回值
setGeolocation
v1.9 版本前添加设置浏览器上下文的定位信息。传入 null
或 undefined
可模拟定位不可用状态。
用法
await browserContext.setGeolocation({ latitude: 59.95, longitude: 30.31667 });
建议使用 browserContext.grantPermissions() 来授予浏览器上下文页面读取定位信息的权限。
参数
返回值
setOffline
在 v1.9 版本前添加用法
await browserContext.setOffline(offline);
参数
返回值
storageState
v1.9 版本前添加返回浏览器上下文的存储状态,包含当前 cookies、本地存储快照和 IndexedDB 快照。
用法
await browserContext.storageState();
await browserContext.storageState(options);
参数
options
Object (可选)
返回值
unroute
v1.9 版本前添加移除通过 browserContext.route() 创建的路由。当未指定 handler 时,会移除所有匹配 url 的路由。
用法
await browserContext.unroute(url);
await browserContext.unroute(url, handler);
参数
-
url
string | RegExp | function(URL):boolean#用于注册路由的全局匹配模式、正则表达式或接收 URL 的谓词函数,通过 browserContext.route() 注册。
-
handler
function(Route, Request):Promise<Object> | Object (可选)#可选的处理函数,用于通过 browserContext.route() 注册路由。
返回值
unrouteAll
添加于: v1.41移除所有通过 browserContext.route() 和 browserContext.routeFromHAR() 创建的路由。
用法
await browserContext.unrouteAll();
await browserContext.unrouteAll(options);
参数
options
Object (可选)-
behavior
"wait" | "ignoreErrors" | "default" (可选)#指定是否等待正在运行的处理器完成以及如何处理它们抛出的错误:
'default'
- 不等待当前处理器调用(如果有)完成,如果取消路由的处理器抛出错误,可能会导致未处理的错误'wait'
- 等待当前处理器调用(如果有)完成'ignoreErrors'
- 不等待当前处理器调用(如果有)完成,取消路由后处理器抛出的所有错误将被静默捕获
-
返回值
waitForEvent
v1.9 版本前添加等待事件触发并将其值传递给断言函数。当断言函数返回真值时返回。如果上下文在事件触发前关闭,将抛出错误。返回事件数据值。
用法
const pagePromise = context.waitForEvent('page');
await page.getByRole('button').click();
const page = await pagePromise;
参数
-
事件名称,与传入
browserContext.on(event)
的名称相同。 -
optionsOrPredicate
function | Object (可选)#-
predicate
function接收事件数据,当等待应解决时解析为真值。
-
timeout
number (可选)最大等待时间(毫秒)。默认为
0
- 无超时。默认值可通过配置中的actionTimeout
选项或使用 browserContext.setDefaultTimeout() 方法更改。
可以是一个接收事件的断言函数,也可以是一个选项对象。可选。
-
-
options
Object (可选)
返回值
属性
clock
Added in: v1.45Playwright 具有模拟时钟和时间流逝的能力。
用法
browserContext.clock
类型
request
Added in: v1.16与该上下文关联的 API 测试辅助工具。使用此 API 发出的请求将使用上下文 cookies。
用法
browserContext.request
类型
tracing
Added in: v1.12用法
browserContext.tracing
类型
事件
on('backgroundpage')
Added in: v1.11仅适用于 Chromium 浏览器的持久化上下文。
当上下文中创建新的后台页面时触发。
const backgroundPage = await context.waitForEvent('backgroundpage');
用法
browserContext.on('backgroundpage', data => {});
事件数据
on('close')
Added before v1.9当浏览器上下文关闭时触发。可能由以下原因之一引起:
- 浏览器上下文被关闭
- 浏览器应用程序被关闭或崩溃
- 调用了 browser.close() 方法
用法
browserContext.on('close', data => {});
事件数据
on('console')
Added in: v1.34当页面中的 JavaScript 调用 console API 方法(如 console.log
或 console.dir
)时触发。
传递给 console.log
的参数和页面信息可通过 ConsoleMessage 事件处理程序参数获取。
用法
context.on('console', async msg => {
const values = [];
for (const arg of msg.args())
values.push(await arg.jsonValue());
console.log(...values);
});
await page.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
事件数据
on('dialog')
Added in: v1.34当出现 JavaScript 对话框时触发,例如 alert
、prompt
、confirm
或 beforeunload
。监听器必须调用 dialog.accept() 或 dialog.dismiss() 来处理对话框 - 否则页面会因等待对话框而冻结,像点击这样的操作将永远无法完成。
用法
context.on('dialog', dialog => {
dialog.accept();
});
当没有 page.on('dialog') 或 browserContext.on('dialog') 监听器时,所有对话框会自动关闭。
事件数据
on('page')
v1.9 版本前添加当 BrowserContext 中创建新 Page 时触发该事件。此时页面可能仍在加载中。该事件也会针对弹出页面触发。另请参阅 page.on('popup') 来接收与特定页面相关的弹出窗口事件。
页面可用的最早时机是当它导航到初始 URL 时。例如,当使用 window.open('http://example.com')
打开弹出窗口时,该事件会在完成对 "http://example.com" 的网络请求且其响应开始在弹出窗口中加载时触发。如果您想路由/监听此网络请求,请使用 browserContext.route() 和 browserContext.on('request') 而非 Page 上的类似方法。
const newPagePromise = context.waitForEvent('page');
await page.getByText('open new page').click();
const newPage = await newPagePromise;
console.log(await newPage.evaluate('location.href'));
使用 page.waitForLoadState() 可以等待页面达到特定状态(在大多数情况下您不需要这样做)。
用法
browserContext.on('page', data => {});
事件数据
on('request')
Added in: v1.12当通过该上下文创建的任何页面发起请求时触发。request 对象是只读的。若只需监听特定页面的请求,请使用 page.on('request')。
要拦截并修改请求,请参阅 browserContext.route() 或 page.route()。
用法
browserContext.on('request', data => {});
事件数据
on('requestfailed')
Added in: v1.12当请求失败时触发(例如超时)。若只需监听特定页面的失败请求,请使用 page.on('requestfailed')。
从 HTTP 角度看,诸如 404 或 503 等错误响应仍属于成功响应,因此请求会通过 browserContext.on('requestfinished') 事件完成,而不会触发 browserContext.on('requestfailed')。
用法
browserContext.on('requestfailed', data => {});
事件数据
on('requestfinished')
添加于: v1.12当请求在下载响应体后成功完成时触发。对于成功的响应,事件顺序为 request
、response
和 requestfinished
。要监听特定页面的成功请求,请使用 page.on('requestfinished')。
用法
browserContext.on('requestfinished', data => {});
事件数据
on('response')
添加于: v1.12当收到请求的response状态和头部时触发。对于成功的响应,事件顺序为 request
、response
和 requestfinished
。要监听特定页面的响应事件,请使用 page.on('response')。
用法
browserContext.on('response', data => {});
事件数据
on('serviceworker')
添加于: v1.11Service workers 仅在基于 Chromium 的浏览器中受支持。
当上下文中创建新的 service worker 时触发。
用法
browserContext.on('serviceworker', data => {});
事件数据
on('weberror')
Added in: v1.38当该上下文中任何页面出现未捕获的异常时触发。如需监听特定页面的错误,请改用 page.on('pageerror')。
用法
browserContext.on('weberror', data => {});
事件数据
已弃用
setHTTPCredentials
Added before v1.9浏览器在成功认证后可能会缓存凭据。请改为创建新的浏览器上下文。
用法
await browserContext.setHTTPCredentials(httpCredentials);
参数
返回值