使用PhantomJS渲染Chart.js图表时出现ReferenceError错误求助
问题描述
尝试使用PhantomJS渲染Chart.js图表时,运行命令phantomjs.exe script.js出现错误ReferenceError: Can't find variable: Chart,但直接在浏览器中打开待渲染的HTML文件时无此问题。使用的PhantomJS版本为2.1.1。
相关代码
PhantomJS脚本文件
page = require('webpage').create(); page.open('file:///path/to/file.html', function() { page.viewportSize = { width: 850, height: 300 }; page.render('graph.png'); phantom.exit(0); });
待渲染的file.html内容
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <div> <canvas id="myChart"></canvas> </div> <script> const ctx = document.getElementById('myChart'); new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true } } } }); </script> </body> </html>
解决方案
问题根源在于两点:一是PhantomJS 2.1.1基于旧版WebKit内核,对ES6语法和新版Chart.js兼容性差;二是页面资源未完全加载就执行了渲染操作。以下是具体修复步骤:
1. 更换兼容的Chart.js版本
PhantomJS 2.1.1无法适配最新版Chart.js,改用对旧环境更友好的2.9.x版本,修改HTML中的脚本引用:
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script>
2. 替换ES6语法为ES5兼容写法
将HTML脚本中的const改为var,避免旧内核不支持的语法:
var ctx = document.getElementById('myChart');
3. 等待资源完全加载后再渲染
不要在page.open回调中直接执行渲染,确保Chart.js加载完成、图表渲染完毕后再导出图片。有两种实现方式:
方式一:固定延迟等待
通过setTimeout设置一段延迟,确保资源加载完成:
page = require('webpage').create(); page.open('file:///path/to/file.html', function(status) { if (status !== 'success') { console.log('页面加载失败'); phantom.exit(1); } page.viewportSize = { width: 850, height: 300 }; // 延迟2秒等待资源加载和图表渲染 setTimeout(function() { page.render('graph.png'); phantom.exit(0); }, 2000); });
方式二:动态检查Chart变量
通过循环检查Chart变量是否存在,比固定延迟更可靠:
page = require('webpage').create(); page.open('file:///path/to/file.html', function(status) { if (status !== 'success') { console.log('页面加载失败'); phantom.exit(1); } page.viewportSize = { width: 850, height: 300 }; // 每隔100ms检查一次Chart是否加载完成 var checkInterval = setInterval(function() { var chartLoaded = page.evaluate(function() { return typeof Chart !== 'undefined'; }); if (chartLoaded) { clearInterval(checkInterval); // 再等待500ms确保图表渲染完成 setTimeout(function() { page.render('graph.png'); phantom.exit(0); }, 500); } }, 100); });
内容的提问来源于stack exchange,提问作者Mayuna
相关产品推荐
相关产品推荐

