На моем сервере (Ubuntu 14.04.4 LTS) у меня установлен Firefox, а также xvfb
для работы без Firefox и CasperJS со SlimerJS. У меня также есть скрипт 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 — но при доступе через веб-сервер сообщается та же ошибка, что и ниже)
Когда я запускаю этот скрипт PHP из командной строки терминала (через SSH), то есть через PHP в режиме CLI:
$ 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]
Итак, по-видимому, мой обезглавленный Firefox не хочет запускаться, когда PHP вызывается через веб-сервер (в этом случае PHP сообщает, что использует apache2handler
SAPI).
Кто-нибудь знает, почему это происходит — и как я могу заставить скрипт правильно выполняться при вызове с веб-сервера, так же как когда он работает в режиме PHP CLI?
РЕДАКТИРОВАТЬ 2: Теперь можно восстановить эту ошибку также в режиме CLI, и может подтвердить, что это из-за пользователя; поэтому без какого-либо сценария JS, представленного в $command
Я получаю это:
$ 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
Ну, это была неприятная проблема. Я закончил тем, что делал strace
и сравнение журналов, для root
пользователь и www-data
пользователь при запуске полного slimerjs
(полную командную строку можно найти, добавив echo
как /path/to/slimerjs-0.10.1-pre/slimerjs
):
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
«s $HOME
является /var/www
где, по-видимому, нет доступа для записи!
Поэтому для меня проще всего было взломать $HOME
переменная среды в mytest.php
сценарий, и установите его /tmp
, где www-data
определенно имеет права на запись:
...
putenv("SLIMERJSLAUNCHER=/usr/bin/firefox46");
putenv("HOME=/tmp");
...
… и теперь, наконец, сценарий работает под www-data
пользователь из CLI тоже:
$ 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 ,
Других решений пока нет …