- 后端
- 图像处理
【免费下载链接】browsershot
Convert HTML to an image, PDF or string
导读
Browsershot 是 Spatie 出品的 PHP 包,用于把 HTML 页面转换为图片、PDF 或字符串,其底层通过 Puppeteer 驱动无头 Chrome。当页面在渲染过程中产生 JavaScript 错误、网络告警或业务日志时,这些信息默认不会出现在截图或 PDF 中,排查问题往往只能靠外部手段。本文介绍的consoleMessages()方法可以一次性抓取页面加载期间 Chrome 控制台的全部输出(log、error、warning等),并附带触发位置信息,帮助你以纯 PHP 的方式拿到页面运行时的真实状态;读完本文,你将掌握该方法的调用方式、返回结构、源码级实现链路,以及如何把它与pageErrors()、failedRequests()等兄弟方法组合成一套完整的页面诊断方案。
基本用法:一行代码拿到控制台全部输出
原文档给出的用法非常简洁:直接调用consoleMessages()即可,无需任何额外配置。
use Spatie\Browsershot\Browsershot; $consoleMessages = Browsershot::url('https://example.com')->consoleMessages(); // returns an array var_dump($consoleMessages);该方法同样适用于 HTML 输入。当通过Browsershot::html($html)传入页面内容时,createConsoleMessagesCommand() 会先把 HTML 写入临时文件并以file://URL 交给浏览器,逻辑与 URL 模式完全一致:
$consoleMessages = Browsershot::html('<script>console.warn("hello from inline html")</script>')->consoleMessages();返回值在正常情况下是一个数组;如果页面加载期间没有任何控制台输出,或浏览器调用未成功,从返回类型看该方法也可能返回null(见 Browsershot.php 中的?array声明),因此生产代码建议先判空再遍历。
返回结构:每个条目包含哪些字段
consoleMessages()返回的是一个二维数组:外层数组的每一项对应一条控制台消息,每个条目本身又是一个关联数组。原文档明确了以下三个核心键:
type:输出类型,例如log、error、warning等(对应 Chrome DevTools Console API 的类型体系,常见取值还包括debug、info、dir、trace、assert、table等);message:消息本身的文本内容;location:关于该消息在何处触发的位置信息,通常包含url键(消息触发页面的 URL),某些场景下还包含行号、列号等定位信息。
需要特别说明的是:从仓库源码看,实际返回的数据比文档描述的多一个字段。在 bin/browser.cjs 的控制台监听器 中,每条消息被构造为:
page.on('console', (message) => consoleMessages.push({ type: message.type(), message: message.text(), location: message.location(), stackTrace: message.stackTrace(), }) );即每个条目还包含stackTrace(调用栈)字段,这与 ChromiumResult.php 中的 PHPDoc 注解 一致。因此实际可用的键为:type、message、location、stackTrace。stackTrace对定位深层错误来源尤其有价值,例如由第三方库内部抛出的异常,仅靠location往往只能看到入口调用点。
一个典型的返回示例:
[ [ 'type' => 'warning', 'message' => 'Slow network detected. See https://www.chromestatus.com/feature/5636954674692096 for more details.', 'location' => [ 'url' => 'https://example.com/', ], 'stackTrace' => '', ], [ 'type' => 'error', 'message' => 'Uncaught ReferenceError: foo is not defined', 'location' => [ 'url' => 'https://example.com/app.js', ], 'stackTrace' => 'at https://example.com/app.js:12:5', ], ]源码级实现链路:从 PHP 方法到 Puppeteer 事件
理解底层链路有助于判断该方法的边界与开销。完整调用链如下:
- PHP 侧发起命令:
consoleMessages()先检查当前实例是否已有缓存结果($this->chromiumResult?->getConsoleMessages()),没有则调用createConsoleMessagesCommand()生成命令,再通过callBrowser()执行(见 Browsershot.php#L838-L853)。 - 命令组装:
createConsoleMessagesCommand()最终调用createCommand($url, 'consoleMessages'),把url、action(值为consoleMessages)以及合并后的浏览器选项打包成一个数组(见 createCommand() 实现)。该数组会被序列化后作为参数传给 Node 脚本bin/browser.cjs。 - 浏览器侧监听:
bin/browser.cjs在page.goto之前注册page.on('console', ...)监听器,把每条控制台消息追加到模块级的consoleMessages数组(见 bin/browser.cjs#L255-L262),该数组随后被放进统一输出对象中(见 getOutput())。 - 结果回传:Node 进程以 JSON 形式输出,PHP 侧用
new ChromiumResult(json_decode($rawOutput, true))解析,其中consoleMessages被存入ChromiumResult对象(见 ChromiumResult.php#L61-L70),最终由getConsoleMessages()取回。
需要注意的是,这条链路意味着consoleMessages()会真实地启动(或连接)一次浏览器并完整加载页面,其耗时和资源开销与一次screenshot()相当,默认超时为 60 秒(见src/Browsershot.php中的$timeout属性)。它并不是对一次已完成的截图调用做“事后补查”,而是独立的浏览器调用;这一点从测试与callBrowser()每次调用都会重建ChromiumResult的实现可以印证(见 callBrowser())。
与pageErrors()、failedRequests()组合成页面诊断矩阵
consoleMessages并不是唯一的页面诊断出口。从 bin/browser.cjs 的统一输出对象 可以看到,一次浏览器调用可以同时收集五类数据:
| 数据键 | PHP 获取方法 | 内容 |
|---|---|---|
consoleMessages | consoleMessages() | 控制台日志(console.log/warn/error等) |
pageErrors | pageErrors() | 未捕获的页面级 JS 异常 |
failedRequests | failedRequests() | 加载失败的请求(如 404 资源) |
redirectHistory | redirectHistory() | 页面重定向历史 |
requestsList | requestsList() | 页面发出的全部请求 |
例如,要完整检查一个页面是否有问题,可以组合调用:
$result = Browsershot::url('https://example.com'); $consoleMessages = $result->consoleMessages(); $pageErrors = $result->pageErrors(); // 未捕获异常,见 src/Browsershot.php#L878 $failedRequests = $result->failedRequests(); // 失败请求,见 docs/miscellaneous-options/getting-failed-requests.md需要指出,以上方法各自都会触发一次独立的浏览器加载(pageErrors()、failedRequests()的实现模式与consoleMessages()完全一致,均先检查缓存再callBrowser)。若页面加载开销较大,可在单次调用中复用同一个Browsershot实例以减少重复配置,但无法在一次页面加载内同时取回多类数据。
典型实战场景
1. 页面健康巡检 / CI 冒烟测试。在部署流水线中,用consoleMessages()断言页面没有error级别的输出:
$errors = array_filter( Browsershot::url($deployedUrl)->consoleMessages() ?? [], fn ($message) => $message['type'] === 'error' ); if (count($errors) > 0) { throw new RuntimeException('页面存在 JS 错误:' . json_encode($errors, JSON_UNESCAPED_UNICODE)); }2. 捕获异步数据加载的告警。前端在fetch失败时通常只会console.warn,页面截图可能依然“看起来正常”,此时结合type === 'warning'与location['url']可以快速定位到具体脚本。
3. 调试生产环境的渲染差异。用location字段确认控制台输出究竟来自主页面还是某个 iframe / 子资源脚本,缩小排查范围。
测试验证:仓库如何保证该功能可用
仓库在 tests/BrowsershotTest.php#L1066-L1073 中提供了专门针对该功能的集成测试:
it('can get the console messages', function () { $consoleMessages = Browsershot::url('https://bitsofco.de/styling-broken-images/')->consoleMessages(); expect($consoleMessages)->toBeArray() ->and($consoleMessages[0]['type'])->toBeString() ->and($consoleMessages[0]['message'])->toBeString() ->and($consoleMessages[0]['location']['url'])->toBeString(); });该测试直接命中一个包含损坏图片的真实页面,验证了返回数组的形态与三个核心键(type、message、location.url)的存在性。从 CHANGELOG.md 可知,consoleMessages方法自 3.55.0(2022-06-13)版本引入,属于长期稳定维护的公开 API。
使用注意与限制
- 返回值可能为
null:当页面没有控制台输出或调用异常时,consoleMessages()可能返回null(PHP 返回类型为?array),遍历前务必判空。 - 每条消息的
location结构:文档将其描述为“数组”,实际由 Puppeteer 的message.location()返回,通常包含url,是否含行号/列号取决于 Puppeteer 版本与消息类型,代码中不应假设字段齐全。 - 独立浏览器调用:该方法会重新加载页面,不适合在超大规模循环中频繁调用;建议配合
setTimeout()调整默认超时(默认为 60 秒)。 - 需要可执行的 Node/Puppeteer 环境:与 Browsershot 其他功能一致,本方法依赖仓库 bin/browser.cjs 脚本及安装好的 puppeteer,环境要求参见 docs/requirements.md。
小结
consoleMessages()是 Browsershot 中低成本、零侵入获取页面运行时信息的关键入口:一条链式调用即可拿到 Chrome 控制台的完整输出,配合type、message、location(以及源码中额外暴露的stackTrace)字段,足以支撑大多数页面 JS 问题的定位需求。将其与pageErrors()、failedRequests()组合使用,你可以在纯 PHP 侧构建起一套不依赖浏览器 DevTools 手工操作的自动化页面诊断能力。
- 后端
- 图像处理
【免费下载链接】browsershot
Convert HTML to an image, PDF or string
相关推荐
Flet WebView 控制台消息事件 WebViewConsoleMessageEvent:捕获 JavaScript console 日志的完整指南
Flet WebView 控制台消息事件 WebViewConsoleMessageEvent:捕获 JavaScript console 日志的完整指南 导读
前端跨平台桌面应用移动开发Elsa Diagnostics Console Logs:在 .NET 工作流引擎中实时捕获与安全流式输出后端控制台日志
Elsa Diagnostics Console Logs:在 .NET 工作流引擎中实时捕获与安全流式输出后端控制台日志 Elsa.Diagnostics.C
后端工作流自动化流程编排低代码Elsa 诊断模块实战:Elsa.Diagnostics.ConsoleLogs 控制台日志实时捕获、缓冲与流式输出完全指南
Elsa 诊断模块实战:Elsa.Diagnostics.ConsoleLogs 控制台日志实时捕获、缓冲与流式输出完全指南 Elsa.Diagnostics.
后端工作流自动化流程编排低代码
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考