元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
入门指南
Playwright安装与配置
环境要求与验证
第一个自动化测试脚本
▶
核心概念
Browser对象详解
Page对象操作指南
Frame与上下文管理
网络请求拦截与Mock
▶
元素定位与操作
CSS选择器实战
XPath高级定位技巧
文本定位与正则匹配
动态元素等待策略
▶
高级操作指南
文件上传下载处理
多标签页与弹窗管理
浏览器上下文隔离
设备模拟与地理定位
▶
测试框架集成
Jest集成配置
Mocha测试报告生成
持续集成CI/CD配置
▶
最佳实践
测试用例组织结构
性能优化策略
跨浏览器测试方案
▶
疑难解答
常见错误代码解析
元素定位失败分析
浏览器启动问题排查
▶
录制功能指南
录制功能基础入门
录制脚本生成与编辑
高级录制配置与技巧
录制脚本调试与优化
发布时间:
2025-03-27 18:39
↑
☰
# 网络请求拦截与Mock 本文将详细介绍如何在Playwright中拦截和模拟网络请求,帮助你实现更灵活的自动化测试场景。 ## 网络请求拦截基础 ### 1. 启用请求拦截 ```typescript // 创建上下文时启用 const context = await browser.newContext({ serviceWorkers: 'block' // 阻止Service Worker }); // 设置请求拦截器 await page.route('**/*.{png,jpg,jpeg}', route => { route.abort(); // 阻止图片加载 }); ``` ### 2. 请求匹配模式 ```typescript // 精确URL匹配 await page.route('https://api.example.com/data', handler); // 通配符匹配 await page.route('**/api/**', handler); // 正则表达式匹配 await page.route(/\.png$/, handler); // 多个URL匹配 await page.route(['**/api/v1/**', '**/api/v2/**'], handler); ``` ## 请求处理 ### 1. 请求信息获取 ```typescript await page.route('**/api/**', async route => { // 获取请求信息 const request = route.request(); // 请求URL console.log(request.url()); // 请求方法 console.log(request.method()); // 请求头 console.log(request.headers()); // 请求体 console.log(await request.postData()); // 资源类型 console.log(request.resourceType()); }); ``` ### 2. 请求操作 ```typescript // 继续请求 await route.continue(); // 中止请求 await route.abort(); // 修改请求 await route.continue({ url: 'https://modified-url.com', method: 'POST', headers: { ...route.request().headers(), 'Custom-Header': 'value' }, postData: JSON.stringify({ key: 'value' }) }); ``` ## Mock响应 ### 1. 基本响应Mock ```typescript // Mock JSON响应 await page.route('**/api/data', route => { route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ message: 'Hello from mock!' }) }); }); // Mock HTML响应 await page.route('**/page', route => { route.fulfill({ status: 200, contentType: 'text/html', body: '<html><body>Mocked page</body></html>' }); }); ``` ### 2. 高级响应Mock ```typescript // 延迟响应 await page.route('**/api/slow', async route => { await new Promise(f => setTimeout(f, 1000)); route.fulfill({ status: 200, body: 'Delayed response' }); }); // 条件Mock await page.route('**/api/conditional', route => { const headers = route.request().headers(); if (headers['authorization']) { route.fulfill({ status: 200, body: 'Authorized' }); } else { route.fulfill({ status: 401, body: 'Unauthorized' }); } }); ``` ## 网络事件监听 ### 1. 请求事件 ```typescript // 监听所有请求 page.on('request', request => { console.log(`请求开始: ${request.url()}`); }); // 监听请求失败 page.on('requestfailed', request => { console.log(`请求失败: ${request.url()}`); console.log('失败原因:', request.failure().errorText); }); // 监听请求完成 page.on('requestfinished', request => { console.log(`请求完成: ${request.url()}`); }); ``` ### 2. 响应事件 ```typescript // 监听响应 page.on('response', response => { console.log(`响应状态: ${response.status()}`); console.log(`响应URL: ${response.url()}`); }); ``` ## 最佳实践 1. 选择性拦截 ```typescript // 只拦截需要的请求 await page.route('**/api/**', route => { if (route.request().resourceType() === 'fetch') { // 处理API请求 route.fulfill({ status: 200, body: JSON.stringify({ data: 'mocked' }) }); } else { // 其他请求正常处理 route.continue(); } }); ``` 2. 模拟网络条件 ```typescript // 模拟慢速网络 await context.route('**/*', async route => { await new Promise(f => setTimeout(f, 100)); route.continue(); }); // 模拟离线状态 await context.setOffline(true); ``` 3. 错误处理 ```typescript // 优雅处理请求错误 try { await page.route('**/api/**', async route => { try { const response = await route.fetch(); const data = await response.json(); route.fulfill({ status: 200, body: JSON.stringify(data) }); } catch (error) { route.fulfill({ status: 500, body: JSON.stringify({ error: 'Internal error' }) }); } }); } catch (error) { console.error('路由设置失败:', error); } ``` ## 常见问题 ### 1. 跨域请求 ```typescript // 处理跨域请求 await page.route('**/api/**', route => { route.fulfill({ status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': '*' }, body: JSON.stringify({ data: 'response' }) }); }); ``` ### 2. 缓存问题 ```typescript // 禁用缓存 await page.route('**/*', route => { route.continue({ headers: { ...route.request().headers(), 'Cache-Control': 'no-cache' } }); }); ``` ## 下一步 1. 学习[CSS选择器实战](/article/playwright/element-locators/css-selector)的使用方法 2. 了解[XPath高级定位技巧](/article/playwright/element-locators/xpath) 3. 掌握[文本定位与正则匹配](/article/playwright/element-locators/text-matching) ## 参考资料 - [Playwright网络API](https://playwright.dev/docs/api/class-route) - [Playwright请求拦截](https://playwright.dev/docs/network) - [Playwright Mock指南](https://playwright.dev/docs/mock)