Chrome DevTools Protocol (CDP)
Get tab WebSocket URL first: Never connect to ws://localhost:9222/devtools/browser directly. Fetch http://localhost:9222/json/list and use webSocketDebuggerUrl from the active tab.
Enable domains before use: Runtime.enable and Page.enable must be called before any Runtime.evaluate or Page.navigate commands.
CDP is async: Wait for response before sending next command. Use Promise-based wrapper with response ID tracking.
Screenshot on high-DPI: Include fromSurface: true and scale: 2 in Page.captureScreenshot params for Retina displays.
Get response body separately: Network.responseReceived doesn't include body. Call Network.getResponseBody with requestId after response completes.
Chrome Extension Manifest V3
Permissions split: Use permissions for APIs, host_permissions for URLs. Never use http://*/* in permissions.
Service workers terminate: No persistent state. Use chrome.storage.local instead of global variables. Use chrome.alarms instead of setInterval.
Content script isolation: Can't access page globals. Use chrome.scripting.executeScript with func for page context. Use window.postMessage for content↔page communication.
Storage is async: chrome.storage.local.get() returns Promise, not data. Always await. Handle QUOTA_EXCEEDED errors.
Context Detection
Detect actual Chrome (not Edge/Brave): Check window.chrome && navigator.vendor === "Google Inc." and exclude Opera/Edge.
Extension context types:
- -
chrome.runtime.id exists → content script - INLINECODE25 exists → popup/background/options
- INLINECODE26 exists but no runtime → regular Chrome web page
Manifest version check: Wrap chrome.runtime.getManifest() in try-catch. Use chrome.action for V3, chrome.browserAction for V2.
Performance Debugging
Memory API conditional: Check 'memory' in performance before accessing performance.memory.usedJSHeapSize.
Use performance marks: performance.mark() and performance.measure() for sub-frame timing. Clear marks to prevent memory leaks.
Layout thrash detection: PerformanceObserver with entryTypes: ['measure', 'paint', 'largest-contentful-paint']. Flag entries >16.67ms.
Network Debugging
Block before navigate: Call Network.setBlockedURLs before Page.navigate, not after.
Request interception: Use Network.setRequestInterception with requestStage: 'Request' for granular control. Return errorReason: 'BlockedByClient' to block.
Security Contexts
Mixed content: HTTPS pages can't load HTTP resources. Check location.protocol vs resource URL.
CORS errors: TypeError on cross-origin fetch usually means CORS. Check DevTools Network tab for specific error.
Secure context required: File System Access API, Clipboard API require window.isSecureContext === true and user gesture.
Chrome DevTools协议 (CDP)
先获取标签页WebSocket URL:切勿直接连接ws://localhost:9222/devtools/browser。请先获取http://localhost:9222/json/list,然后使用活动标签页中的webSocketDebuggerUrl。
使用前启用域:在调用任何Runtime.evaluate或Page.navigate命令之前,必须先调用Runtime.enable和Page.enable。
CDP是异步的:在发送下一条命令之前,请等待响应。使用基于Promise的封装,并跟踪响应ID。
高DPI屏幕截图:对于Retina显示屏,在Page.captureScreenshot参数中包含fromSurface: true和scale: 2。
单独获取响应体:Network.responseReceived不包含响应体。在响应完成后,使用requestId调用Network.getResponseBody。
Chrome扩展程序 Manifest V3
权限拆分:使用permissions表示API,使用host_permissions表示URL。切勿在permissions中使用http:///。
Service Worker会终止:无持久状态。使用chrome.storage.local代替全局变量。使用chrome.alarms代替setInterval。
内容脚本隔离:无法访问页面全局变量。使用带func参数的chrome.scripting.executeScript来访问页面上下文。使用window.postMessage进行内容脚本↔页面通信。
存储是异步的:chrome.storage.local.get()返回Promise,而非数据。始终使用await。处理QUOTA_EXCEEDED错误。
上下文检测
检测真正的Chrome(非Edge/Brave):检查window.chrome && navigator.vendor === Google Inc.,并排除Opera/Edge。
扩展上下文类型:
- - chrome.runtime.id存在 → 内容脚本
- chrome.runtime.getManifest存在 → 弹出窗口/后台/选项页面
- chrome.loadTimes存在但无runtime → 普通Chrome网页
Manifest版本检查:将chrome.runtime.getManifest()包裹在try-catch中。V3使用chrome.action,V2使用chrome.browserAction。
性能调试
条件性内存API:在访问performance.memory.usedJSHeapSize之前,检查memory in performance。
使用性能标记:使用performance.mark()和performance.measure()进行子帧计时。清除标记以防止内存泄漏。
布局抖动检测:使用entryTypes: [measure, paint, largest-contentful-paint]的PerformanceObserver。标记超过16.67ms的条目。
网络调试
导航前拦截:在Page.navigate之前调用Network.setBlockedURLs,而非之后。
请求拦截:使用带requestStage: Request的Network.setRequestInterception进行精细控制。返回errorReason: BlockedByClient以阻止请求。
安全上下文
混合内容:HTTPS页面无法加载HTTP资源。检查location.protocol与资源URL。
CORS错误:跨域fetch时的TypeError通常意味着CORS问题。查看DevTools网络标签页以获取具体错误。
需要安全上下文:文件系统访问API、剪贴板API需要window.isSecureContext === true和用户手势。