【问题标题】:Running a SlimerJS + headless Firefox script through PHP on webserver?在网络服务器上通过 PHP 运行 SlimerJS + 无头 Firefox 脚本?
【发布时间】:2016-06-30 13:49:48
【问题描述】:

在我的服务器(Ubuntu 14.04.4 LTS)上,我安装了 Firefox,以及用于无头 Firefox 操作的 xvfb,以及带有 SlimerJS 的 CasperJS。我也有一个运行良好的 CasperJS 脚本。我想从 PHP 中使用这个脚本;这是我的PHP脚本的精髓,我们称之为mytest.php

echo "php_sapi_name() " . php_sapi_name() . "\n"; // "cli" for php cli, "apache2handler" for php via webserver

chdir(dirname(__FILE__));

$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules";

putenv("SLIMERJSLAUNCHER=/usr/bin/firefox46");
$cmdline = "xvfb-run $nodeModPath/casperjs/bin/casperjs --engine=slimerjs --debug=true mySlimerScript.js";

$returnString = shell_exec($cmdline);
echo "$returnString\n";

编辑:请注意,该命令也可以是:

$cmdline = "xvfb-run $nodeModPath/casperjs/bin/casperjs --engine=slimerjs --debug=true 2>&1";

...也就是说,没有列出任何 JS 脚本 - 在这种情况下,应该转储帮助(并且在 CLI 访问的情况下 - 但通过 webserver 访问时会报告与以下相同的错误)


当我从终端命令行(通过 SSH)运行这个 PHP 脚本时,即在 CLI 模式下通过 PHP:

$ php mytest.php 

...一切正常,没有任何问题。

但是,当我通过网络服务器在线调用这个 PHP 脚本时,即通过http://example.com/mytest.php,它首先失败并出现错误:

Gecko error: it seems /usr/bin/firefox46 is not compatible with SlimerJS.
See Gecko version compatibility. If version is correct, launch slimerjs
with --debug=true to see Firefox error message

...在添加--debug=true(已包含在上面的示例中)之后,我还收到此错误:

JavaScript error: resource://gre/modules/FileUtils.jsm, line 63: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIProperties.get]

所以,当通过网络服务器调用 PHP 时,显然我的无头 Firefox 不想运行(在这种情况下,PHP 报告它使用apache2handler SAPI)。

有人知道为什么会发生这种情况吗?我怎样才能让脚本在从网络服务器调用时正确执行,就像它在 PHP CLI 模式下运行时一样?


编辑 2:现在也可以通过 CLI 模式重建此错误,并且可以确认它是由于用户造成的;所以没有$command中提供的任何JS脚本,我得到这个:

$ sudo -H -u root php mytest.php
...
Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]]
       casperjs [options] test [test path [test path ...]]
       casperjs [options] selftest
...

$ sudo -H -u www-data php mytest.php
JavaScript error: resource://gre/modules/FileUtils.jsm, line 63: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIProperties.get]
Gecko error: it seems /usr/bin/firefox46 is not compatible with SlimerJS.
See Gecko version compatibility. If version is correct, launch slimerjs
with --debug=true to see Firefox error message

【问题讨论】:

  • 第一个想法:在cli 模式下运行脚本的文件权限将让用户运行它,但是,通过网络服务器,用户将是www-data。可能,不是吗?
  • 确实,@php-dev,但我无法确定谁的权限会成为问题;在这里我调用xvfb-run,它调用casperjs,它调用slimerjs,它调用headless Firefox。在这种情况下,有没有办法在某处检查权限错误?我试过/var/log/apache2/error-mysite.log,但是一旦shell_exec调用失败,它只会报告像Trying to get property of non-object这样的PHP内容。
  • 尝试将stderr 输出重定向到stdout 或文件。
  • 感谢@php-dev - 我在$cmdline 的末尾添加了2>&1,但不幸的是我没有得到任何新信息。但是,我也尝试了直接的shell_exec("xvfb-run /usr/bin/firefox46 2>&1"),这个似乎没有崩溃(但是,它也不会像预期的那样自行退出)。看来,xvfb-runfirefox 单独不是问题?!

标签: php firefox slimerjs


【解决方案1】:

嗯,这是一个令人讨厌的问题。我最终做了一个strace,并比较了root用户和www-data用户在运行完整的slimerjs时的日志(可以通过将echoes添加到@987654327来找到完整的命令行@):

sudo -H -u www-data strace \
  /usr/bin/firefox46 -app /path/to/slimerjs-0.10.1-pre/application.ini \
  --profile /path/to/firefox-46.0.1/profile-46 -no-remote --debug=true /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/bootstrap.js --casper-path=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs \
  --cli 2>&1 \
  | tee /tmp/strace.log

sudo -H -u root strace \
  /usr/bin/firefox46 -app /path/to/slimerjs-0.10.1-pre/application.ini \
  --profile /path/to/firefox-46.0.1/profile-46 -no-remote --debug=true /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/bootstrap.js --casper-path=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs \
  --cli 2>&1 \
  | tee /tmp/straceR.log

如果现在以meld 比较这些日志,那么最终会在这样的点开始分歧:

mkdir("/root/.innophi", 0700)           = 0
mkdir("/root/.innophi/slimerjs", 0700)  = 0

... [vs.] ...

mkdir("/var/www/.innophi", 0700)        = -1 EACCES (Permission denied)
access("/var/www/.innophi", F_OK)       = -1 ENOENT (No such file or directory)

所以,casperJS 基本上是尝试在用户的主目录中创建一个目录;问题是,www-data$HOME/var/www,它似乎没有写入权限!

所以,对我来说最简单的事情就是“破解”mytest.php 脚本中的$HOME 环境变量,并将其设置为/tmp,其中www-data 肯定具有写入权限:

...
putenv("SLIMERJSLAUNCHER=/usr/bin/firefox46");
putenv("HOME=/tmp");
...

...whaddayaknow,最后脚本也可以在 CLI 的 www-data 用户下运行:

$ sudo -H -u www-data php test_commands.php
...
Options:

--verbose   Prints log messages to the console
--log-level Sets logging level
--help      Prints this help
...

顺便说一句,这个.innophi目录好像也提到了https://docs.slimerjs.org/current/configuration.html#profiles

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多