为什么我不能将JSON从Ruby发送到Phantomjs

时间:2014-11-06 23:17:59

标签: javascript ruby-on-rails ruby json phantomjs

我正在使用the PhantomJS gem从Ruby调用PhantomJS脚本。

当我需要将HTML发送到我正在调用的PhantomJS脚本时,我已经在我的应用程序中成功使用了这个gem。

但是,当我尝试将JSON发送到我正在调用的PhantomJS脚本时,它失败了。

我调用的PhantomJS脚本是PhantomJS-Google-Charts

我已将脚本的前几行修改为:

var system = require('system');
var fs = require('fs');
var jsonData = fs.open(system.args[1], 'r'); // also tried 'rb'

// exports.generateChart = function(jsonData, callback){
    var page = require('webpage').create();

    page.viewportSize = {width: jsonData.options.width, height: jsonData.options.height};

我做了这些改动,因为(a)在尝试并且没有直接将JSON作为参数发送到脚本后我读到了in situations like my own the only way to send JSON to PhantomJS is to save it to a file and then read it,并且(b)我没有将这个脚本称为模块来自另一个JavaScript脚本 - 我直接从Ruby调用它 - 这意味着我无法使用export

在Ruby中,我这样做:

data = {"type" => "PieChart", "options" => {"title" => "Type of Fruit Eaten", "width" => "400", "height" => "300", "is3D" => true, "pieSliceText" => "value"},"columns" => {"Type" => "string", "Eaten" => "number"}, "rows" => {"Bananas" => 4, "Apples" => 2, "Oranges" => 6, "Mangoes" => 3}}.to_json
require 'tempfile'
file = Tempfile.new("foo")
file.write(data)
file.rewind
Phantomjs.run("./app/assets/javascripts/googleCharts.js", file.path)

为什么我会收到此错误:

"TypeError: 'undefined' is not an object (evaluating 'jsonData.options.width')\n\n  ./app/assets/javascripts/googleCharts.js:43\n"

BTW,第43行(在错误中提到)是:

page.viewportSize = {width: jsonData.options.width, height: jsonData.options.height};

当我在Textmate中打开tempfile时,它看起来像这样:

{"type":"PieChart","options":{"title":"Type of Fruit Eaten","width":"400","height":"300","is3D":true,"pieSliceText":"value"},"columns":{"Type":"string","Eaten":"number"},"rows":{"Bananas":4,"Apples":2,"Oranges":6,"Mangoes":3}}

当我将其粘贴到JSONLint时,会验证。

为什么我在PhantomJS命令行运行脚本(粘贴文件的路径而不是从system.args调用它),我收到此错误:

'page.viewportSize = {width: jsonData.options.width, height: jsonData.options.height};' is a cyclic structure

此时,如果我只输入jsonData.options.width,我会得到:

'jsonData.options.width' is a cyclic structure

如果我只输入jsonData,我会得到:

undefined

1 个答案:

答案 0 :(得分:0)

终于搞定了。

步骤如下:

(1)不要改变googleCharts.js(不像我上面写的那样)。相反,您完全按照https://github.com/pstephan1187/PhantomJS-Google-Charts

使用googleCharts.js

(2)将googleCharts.js放在/app/assets/javascripts中除非你想修改下面的代码

(3)从以下JavaScript脚本中调用googleCharts.js

var GC = require('./googleCharts.js');

var system = require('system');
var fs = require('fs');
var path = system.args[1];
var opened = fs.open(path, "r");
var data = fs.read(path);
var jsonData = JSON.parse(data);

GC.generateChart(jsonData, function(svgHtml){
    console.log(svgHtml);
    phantom.exit();
});

(4)调用该脚本trigger.js并将其放在/app/assets/javascripts中,除非您要修改以下代码

(5)安装PhantomJS gem https://github.com/colszowka/phantomjs-gem

(6)使用以下Ruby调用整个批次:

data = {"type" => "PieChart", "options" => {"title" => "Type of Fruit Eaten", "width" => "400", "height" => "300", "is3D" => true, "pieSliceText" => "value"},"columns" => {"Type" => "string", "Eaten" => "number"}, "rows" => {"Bananas" => 4, "Apples" => 2, "Oranges" => 6, "Mangoes" => 3}}.to_json
require 'tempfile'
file = Tempfile.new(['a', '.txt'], "#{Rails.root}/tmp")
file.write(data)
File.chmod(444, file.path)
file.rewind
Phantomjs.run("./app/assets/javascripts/trigger.js", file.path)

<强>更新

这是一个专门用于展示所有内容的分叉:

https://github.com/snoblenet/PhantomJS-Google-Charts-Ruby