用 webpack 打包的前端页面(比如基于 ECharts 的监控大盘),通常无法在浏览器控制台直接访问图表数据。
问题:echarts 全局不可用
未打包的页面可以用 echarts.getInstanceByDom(el) 获取图表实例并读取数据,但经过 webpack 打包后:
typeof echarts // => "undefined"
window.echarts // => undefined
原因:webpack 默认把模块作用域封闭,echarts 不挂载到 window,除非项目显式配置了 externals 或 ProvidePlugin。
问题:图表渲染在 Canvas
ECharts 默认用 Canvas 渲染,图表数据不在 DOM 里。即使遍历所有元素,也只能找到一个 <canvas> 标签,无法从中提取时序数据。
解决方案:注入 fetch/XHR 拦截器
在页面加载后、图表请求发出前,注入拦截器捕获 API 的原始 JSON 响应:
window.__chartData = {};
const _origFetch = window.fetch;
window.fetch = function(url, options) {
const promise = _origFetch.apply(this, arguments);
if (typeof url === 'string' && url.includes('your-api-domain.com')) {
promise.then(r => r.clone().json().then(data => {
if (!window.__chartData[url]) window.__chartData[url] = [];
window.__chartData[url].push({ req: options?.body, res: data });
}).catch(() => {})).catch(() => {});
}
return promise;
};
注入后触发图表刷新(重新选择时间范围或点击刷新按钮),再读取:
JSON.stringify(window.__chartData)
时机很重要
- 必须在图表发起 API 请求之前注入拦截器
- 如果页面已经加载完毕(初始请求已发出),需要主动触发刷新才能捕获新请求
- XHR 拦截作为 fetch 的兜底,两者都需要处理
这个方案适用于所有基于 webpack 打包、通过 API 获取图表数据的前端页面,不局限于 ECharts。