基于Node.js与PhantomJS实现网页局部截图的技术方案
本文介绍如何利用Node.js与PhantomJS实现网页截图功能。重点讲解如何通过Express接收DOM字符串,利用PhantomJS生成局部页面快照并返回Base64数据。内容涵盖环境配置、核心代码逻辑及跨域处理,帮助开发者快速掌握网页局部截屏的实现方法。
环境配置与准备工作
应项目需求,近期使用PhantomJS与Node.js开发了网页截屏功能。为防止遗忘,现将代码实现细节及配置流程整理如下。
第一步需确保已安装Node.js。相关安装教程网上资源丰富,此处不再赘述,具体可参考Nodejs官网链接。
第二步需获取PhantomJS,访问官网下载对应操作系统的安装包。
第三步是将PhantomJS配置为系统环境变量。以下以Windows系统为例进行配置说明:

配置完成后,在cmd命令行中输入 phantomjs -v 命令以验证配置是否成功。若配置正确,显示结果应如下图所示:

核心代码实现与改造
第四步编写代码。查阅PhantomJS入门文档可知,其支持将网页预览生成图片、PDF或base64格式。本项目需求并非完整网页截图,而是截取网页局部内容,因此需对部分代码进行改造。以下详细讲解代码实现:
4.1) 首先配置Express相关设置。由于需要执行PhantomJS命令,需引入child_process模块。具体代码如下:
var process = require('child_process');//执行命令行所需
var express = require('express');//express
var bodyParser = require('body-parser');
var fs = require("fs");//文件操作
var app = express();
app.use('/pages',express.static('pdfs'));//设置静态资源目录
app.use(bodyParser.json({limit:'50mb'}));//请求内容大小限制
app.use(bodyParser.urlencoded({limit:'50mb',extended:false}));
//设置允许跨域访问
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials','true');
next();
};
app.use(allowCrossDomain);
4.2) 接下来是生成页面Base64数据的接口方法,实现如下:
app.get('/getBase64',function(req,res){
var url=req.query.url;//读取请求中的url参数,然后访问这个url
url=url.replace(/&/g,'%26');//将请求中的&转换
var resp={
"status":'200'
}
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});//设置响应头
if(url==''){
resp.msg='url参数不能为空';
res.end(JSON.stringify(resp));
}
else{
//phantomjs执行的命令行 index.js在后文中给出
var strShell='phantomjs --disk-cache=true --disk-cache-path=. index.js '+url;
process.exec(strShell,{
maxBuffer:5000*1024,
},function(error,stdout,strerr){
if(error!==null){
console.log(error);
resp.msg='转换失败,稍后重试';
res.end(JSON.stringify(resp));
}else{
//执行成功则返回base64的数据
resp.data=stdout;
res.end(JSON.stringify(resp));
}
})
}
})
4.3) PhantomJS执行的脚本文件为index.js,代码如下:
var page = require('webpage').create();//获取webpage
var system = require('system'),
address;
if (system.args.length === 1) {//执行的命令应该包括请求的URL,否则退出phantom
console.log('Usage: URL error');
phantom.exit();
}
address = system.args[1];//请求的地址
address = address.replace(/%26/g, '&');//phantom不能识别%26,所以转为&
page.viewportSize = {//设置viewport
width: 1920,
height: 1080,
}
page.open(address, function(status) {//打开页面
setTimeout(function() {//2s之后获取base64结果,如果直接生成有可能页面还没有加载完成
if (status == 'success') {
var base64 = page.renderBase64('PNG');
console.log(base64);//将base64结果输出之后,在上边的getBase64接口中获取
phantom.exit();
}
}, 2000);
})
4.4) 获取页面局部内容截图。可将需要截图的DOM字符串发送至后台,随后新建一个空页面,使用PhantomJS访问该空白页面,并将DOM字符串添加至预览页面,最后生成截图。具体代码如下:
app.post('/getPartPage', function(req, res) {
var xmlObj = req.body.xmlObj;//获取DOM字符串
const reqUrl = 'http:example.com/tmp.html';//要访问的空页面
var response = {
"status": '200',
};
if (xmlObj == undefined || xmlObj == '' || xmlObj == null) {
response.msg = 'DOM字符串内容未输入';
res.end(JSON.stringify(response));
}else {
fs.writeFile('tmp.txt', xmlObj, function(err) { //由于dom字符串内容过多,所以写入txt文本
if (err) {
response.msg = '生成页面失败,请稍后重试';
return res.end(JSON.stringify(response));
}
var strShell = 'phantomjs pages/index.js ' + reqUrl;//phantomjs执行的命令
process.exec(strShell, {
maxBuffer: 5000 * 1024,
}, function(error, stdout, strerr) {
if (error !== null) {
response.msg = '脚本执行错误,请稍后重试';
res.end(JSON.stringify(response));
} else {
response.data = stdout.replace("\r\n", "");
res.end(JSON.stringify(response));//返回结果
}
})
})
}
})
var server = app.listen(8808,function(){ //接口监听,访问的端口
var host = server.address().address
var port = server.address().port
console.log('http://%s:%s',host,port);
})
4.5) pages目录下的index.js内容如下所示:
var page = require('webpage').create();//获取webpage
var fs = require('fs');
var system = require('system'),
address,filename;
if (system.args.length === 1) {
console.log('Usage: URL error');
phantom.exit();
}
address = system.args[1];//请求的路径
address = address.replace(/%26/g, '&');
filename = (new Data()).getTime();
page.viewportSize = {
width: 750,
}
page.paperSize = { //生成A4大小的PDF文件
format: 'A4',
orientation: 'portrait',
margin: '0.8cm'
}
page.open(address, function(status) {
var info = fs.read('tmp.txt');//读取DOM字符串
var result = page.evaluate(function(info) {
try {
document.querySelector('#dom').innerHTML = info;//将dom字符串拼接
} catch (e) {
console.log(e);
}
return document.querySelector('#dom').innerHTML;//返回页面
}, info);
setTimeout(function() {
page.paperSize = {
format: 'A4',
orientation: 'portrait',
margin: '0.8cm'
};
page.viewportSize = {
width: 750,
};
//生成PDF文件
page.render('pages/' + filename + '.pdf', { format: 'pdf', quality: '100' });
console.log('http://example.com/pages/' + filename + '.pdf');//返回PDF文件的访问路径
phantom.exit();
}, 500);
})
以上即为全部接口内容。完整代码可访问https://github.com/kim095/node-phantom进行下载。希望对各位的学习有所帮助,也欢迎大家继续支持本站。
Java和JavaScript应用场景对比:企业级后端 vs Web前端与Node.js
2026-11-04 16:42:01
JavaScript模块化开发入门:CommonJS与ES Module的区别
2026-11-03 23:31:34
怎么创建并运行第一个js文件
2026-11-03 21:49:02
JavaScript运行环境怎么搭建?Node.js官方下载与安装教程
2026-11-03 20:03:04
NestJS 集成 TypeORM 或 Prisma 实现数据库持久化操作
2026-11-03 18:56:13
