从phantomjs子进程在节点中发送二进制响应
send binary response in node from phantomjs child process
我已经创建了一个节点端点来为我的svg图表创建栅格化版本。
app.post('/dxexport', function(req, res){
node2Phantom.createPhantomProcess(req,res);
});
我的节点到幻影函数使用spawn运行phantomjs
var spawn = require('child_process').spawn;
exports.createPhantomProcess = function(req,res){
var userRequest = JSON.stringify(req.body);
var bin = "node_modules/.bin/phantomjs"
var args = ['./dxexport/exporter-server.js', userRequest, res];
var cspr = spawn(bin, args);
cspr.stdout.on('data', function (data) {
var buff = new Buffer(data);
res.send(data);
});
cspr.stderr.on('data', function (data) {
data += '';
console.log(data.replace("'n", "'nstderr: "));
});
cspr.on('exit', function (code) {
console.log('child process exited with code ' + code);
process.exit(code);
});
};
当渲染完成并成功创建文件时,我在phantomjs
中调用renderCompleted函数:
var renderCompleted = function (parameters) {
var exportFile = fileSystem.open(parameters.exportFileName, "rb"),
exportFileContent = exportFile.read();
parameters.response.statusCode = 200;
parameters.response.headers = {
"Access-Control-Allow-Origin": parameters.url,
"Content-Type": contentTypes[parameters.format],
"Content-Disposition": "attachment; fileName=" + parameters.fileName + "." + parameters.format,
"Content-Length": exportFileContent.length
};
parameters.response.setEncoding("binary");
parameters.response.write(exportFileContent);
/////// somehow send exportFileContent as node res object for download ''''''''
exportFile.close();
parameters.format !== "svg" && fileSystem.remove(parameters.exportFileName);
for (var i = 0; i < parameters.filesPath.length; i++)
fileSystem.remove(parameters.filesPath[i]);
parameters.filesPath = [];
parameters.response.close()
};
这个响应是从nodejs传递的,但显然这段代码正在调用phantomjs
方法,所以我得到像
TypeError: 'undefined'不是一个函数(求值'parameters.response.setEncoding("binary")')
我如何以某种方式将二进制文件响应发送到节点函数,以便它可以与我的节点服务器一起发送给用户?
经过一番努力,如果有人偶然发现这篇文章,这里是有效的解决方案。
正如Artjom b提到的,我发现最简单的方法是将可视化的渲染和文件创建委托给phantomjs。然后通过控制台发送与这些操作相关的所有参数。
也根据@ArtjomB更新了答案。建议将发送的控制台消息包装在一个唯一的开始和结束字符串中,这样可以降低其他可能的未来输出被误认为是预期呈现的文件对象的风险。
var renderCompleted = function (parameters) {
console.log("STRTORNDRD" + JSON.stringify(parameters) + "ENDORNDRD");
};
然后被stdout拾取并像这样使用:
exports.exportVisual = function (req, res) {
var userRequest = JSON.stringify(req.body);
var bin = "node_modules/.bin/phantomjs"
var args = ['./dxexport/exporter-server.js', userRequest, res];
var cspr = spawn(bin, args);
var contentTypes = {
pdf: "application/pdf",
svg: "image/svg+xml",
png: "image/png"
};
cspr.stdout.on('data', function (data) {
var buff = new Buffer(data).toString('utf8');
var strData = buff.match(new RegExp("STRTORNDRD" + "(.*)" + "ENDORNDRD"));
if (strData) {
var parameters = JSON.parse(strData[1]);
var img = fs.readFileSync(parameters.exportFileName);
var headers = {
"Access-Control-Allow-Origin": parameters.url,
"Content-Type": contentTypes[parameters.format],
"Content-Disposition": "attachment; fileName=" + parameters.fileName + "." + parameters.format,
"Content-Length": img.length
};
res.writeHead(200, headers);
res.end(img, 'binary');
// delete files after done
if (parameters.format != "svg") {
fs.unlink(parameters.exportFileName);
}
for (var i = 0; i < parameters.filesPath.length; i++)
fs.unlink(parameters.filesPath[i]);
// done. kill it
cspr.kill('SIGINT');
}
});
cspr.stderr.on('data', function (data) {
data += '';
console.log(data.replace("'n", "'nstderr: "));
});
cspr.on('exit', function (code) {
console.log('child process exited with code ' + code);
process.exit(code);
});
};
相关文章:
- 如何将getJson的响应保存在全局变量中
- 如何将PDF作为二进制文件传递到window.open()
- 如何使用Spring MVC将Facebook返回的响应数据保存在Java类中
- 使用angularjs向浏览器发送servlet响应(下载功能)
- MockJax没有在JavaScript应用程序中发送对我AJAX请求的响应
- 不再使用innerHTML进行AJAX响应.(代码未得到响应)
- 如何将字母转换为二进制代码
- 为什么可以't我使用了AJAX响应的一部分
- 响应动画手风琴不工作
- 如何从SeleniumWebdriver获取异步Javascript响应
- Ajax调用在Firefox中不会自动响应
- 可以在响应时隐藏iphone上的“播放”按钮以进行视频播放
- 由于响应中不存在“Access Control Allow Origin”标头,跨域请求停止工作
- 如何在 JavaScript 和 HTML 中更改对输入框的提示响应
- IIS动态HTTP响应标头
- 预期响应包含一个对象,但在angular js中得到一个数组错误
- 单元测试接收到带有$httpBackend的二进制响应
- 如何强制浏览器打开“另存为”二进制响应对话框
- 从phantomjs子进程在节点中发送二进制响应
- 为什么这个二进制搜索实现会使浏览器无响应?