Intereting Posts
Как использовать подготовленные команды mysqli в PHP? WordPress REST API Медленное время отклика Значение аргумента Objective-C по умолчанию PDO & Sanitize Date / Remove HTML Heroku PHP crash bash: поставщик / bin / heroku-php-apache2: нет такого файла или каталога php делает, пока не будет работать с next-> rowset GET переменные с пробелами – они работают, но это правильно или нормально? Избегайте SQL-инъекции в пользовательском SQL-regex PHP и MySQL: порядок по последней дате и лимиту 10 Тайм-аут сеанса PHP / Javascript с предупреждением Как преобразовать XML с помощью XSLT с помощью PHP в WordPress PHP: Скачать скрипт файла, не работающий на iPad Значение шифрования Mcrypt js отличается от значения, полученного с помощью PHP mcrypt / Mcrypt JS decrypt, не работает для символов UTF-8 В DDD и CQRS для запросов на чтение, что такое стратегия, которая позволяет использовать интерфейсы и простое тестирование? Laravel 5.1 – Тестирование множественного selectbox

PHP Mink / Zombie – просмотр страницы возвращает код состояния 0?

Я должен протестировать логин на сервере, который не под моим контролем, это HTTPS, используя драйвер Mink и Zombie в PHP. Проблема в том, что я в основном получаю код статуса 0 всякий раз, когда я посещаю страницу входа, и поэтому я не могу работать с каким-либо из элементов. Я пробовал использовать Wireshark для проверки сетевого трафика, но поскольку это HTTPS, он зашифрован, и я понятия не имею, что происходит в захватах Wireshark; Я могу видеть только, что некоторые данные были обменены с сервером.

Я не могу передать URL-адрес фактической странице, к которой я пытаюсь получить доступ, но я обнаружил, что могу продемонстрировать ее публичной демонстрацией Centreon (подробнее о https://www.centreon.com/en/centreon-demo/ ; извиниться перед Центроном заранее). Итак, вот пример, который реплицирует эту проблему (моя установка как на nodejs не может найти модуль «зомби» с PHP норкой ):

<?php $nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; # composer autoload: require_once __DIR__ . '/vendor/autoload.php'; $URL = "http://demo.centreon.com/centreon"; $USERNAME = "admin"; $PASSWORD = "centreon"; $LFID = "useralias"; $PFID = "password"; $BFID = "submitLogin"; $zsrv = new \Behat\Mink\Driver\NodeJS\Server\ZombieServer(); $zsrv->setNodeModulesPath($nodeModPath . "/"); # needs to end with a trailing '/' $driver = new \Behat\Mink\Driver\ZombieDriver( $zsrv ); $session = new \Behat\Mink\Session($driver); // start the session $session->start(); $session->setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'); //~ $session->visit($URL); $statcode = 0; while ($statcode != 200) { $isleep = rand(2, 7); echo "sleeping $isleep sec...\n"; sleep($isleep); $session->visit($URL); $statcode = $session->getStatusCode(); echo " current URL: " . $session->getCurrentUrl() ."\n"; echo " status code: " . $statcode ."\n"; } $page = $session->getPage(); $el_login = $page->findField($LFID); $el_password = $page->findField($PFID); $el_button = $page->find('xpath', '//*[@name="'.$BFID.'"]');//findById($BFID);//findField($BFID); //~ var_dump($el_button); $el_login->setValue($USERNAME); $el_password->setValue($PASSWORD); echo " pressing/clicking login button\n"; $el_button->click(); echo "Page URL after click: ". $session->getCurrentUrl() . "\n"; $page = $session->getPage(); ?> 

Теперь, когда я запускаю этот скрипт, я обычно получаю:

 $ php test_php_mink.php sleeping 4 sec... current URL: https://demo.centreon.com/centreon/ status code: 0 sleeping 4 sec... current URL: https://demo.centreon.com/centreon/ status code: 0 sleeping 5 sec... current URL: https://demo.centreon.com/centreon/ status code: 0 ... 

Примечательно, что, когда это происходит, если я обновляю один и тот же URL-адрес в браузере, он возвращает страницу правильно (так что статус 200).

Очень, очень редко, я могу заставить это получить статус 200 и полную загрузку страницы в скрипте; но как только я попробую еще раз после этого, снова получаю статус 0 – вот фрагмент этого (с дополнительной ошибкой JavaScript, которая, по-видимому, связана с сайтом):

 $ php test_php_mink.php sleeping 7 sec... current URL: https://demo.centreon.com/centreon/ status code: 0 sleeping 4 sec... current URL: https://demo.centreon.com/centreon/ status code: 200 pressing/clicking login button PHP Fatal error: Uncaught exception 'Behat\Mink\Exception\DriverException' with message 'Error while processing event 'click': "ReferenceError: Effect is not defined\n at https://demo.centreon.com/centreon/include/common/javascript/modalbox.js:517:1\n at Object.exports.runInContext (vm.js:44:17)\n ... 

Может ли кто-нибудь объяснить, что может быть причиной такого поведения – и есть ли что-нибудь, что я мог бы правильно восстановить страницу в сценарии надежным образом?

Related of "PHP Mink / Zombie – просмотр страницы возвращает код состояния 0?"

Ну, я что-то нашел, но я действительно не уверен, как все должно работать – так что более узнаваемый ответ будет очень оценен.

В любом случае, я немного экспериментировал, и в итоге я обнаружил, что $session->getStatusCode() (скорее всего) определен в ./vendor/behat/mink-zombie-driver/src/ZombieDriver.php как:

 public function getStatusCode() { return (int) $this->server->evalJS('browser.statusCode', 'json'); } 

Итак, в основном, он читает свойство JavaScript browser.statusCode . Оказывается, если мы подождем достаточно долго, чтобы этот код состояния изменился, то загрузка страницы продолжается, и в конце я получаю код состояния 200 (опять же, это для случая, когда обычный браузер всегда правильно читает страницу, тем самым подтверждая, что сеть в порядке). Это изменение, которое я сделал:

 $statcode = 0; while ($statcode != 200) { $isleep = rand(2, 7); echo "sleeping $isleep sec...\n"; sleep($isleep); $session->visit($URL); // $session->wait(20000, '(0 === jQuery.active)'); # Uncaught exception 'RuntimeException' with message 'Could not establish connection: Connection refused (111)' $session->wait(20000, '(browser.statusCode > 0)'); ### THIS makes things work?! $statcode = $session->getStatusCode(); echo " current URL: " . $session->getCurrentUrl() ."\n"; echo " status code: " . $statcode ."\n"; } 

Заметка:

  • Я нашел условие ожидания (0 === jQuery.active) о том, как заставить Behat ждать вызова AJAX? ; здесь, однако, похоже, что это сообщение 'RuntimeException' with message 'Could not establish connection: Connection refused (111)'
  • Даже при условии ожидания (browser.statusCode > 0) это не сработало, как в OP, если я просто использовал случайную задержку сна, т.е. wait($isleep, '(browser.statusCode > 0)'); – Вероятно, потому что $isleep находится в секундах, а wait() ожидает миллисекунды; скрипт начал работать после того, как я явно установил ожидание до 20000 (миллисекунды = 20 секунд, скрипт завершается раньше, чем это).

Теперь, за последние 10-15 раз я запустил скрипт, я понял:

 $ php test_php_mink_timeout.php sleeping 6 sec... current URL: https://demo.centreon.com/centreon/ status code: 200 pressing/clicking login button PHP Fatal error: Uncaught exception 'Behat\Mink\Exception\DriverException' with message 'Error while processing event 'click': "ReferenceError: Effect is not defined\n at https://demo.centreon.com/centreon/include/common/javascript/modalbox.js:517:1\n at Object.exports.runInContext (vm.js:44:17)\n at window._evaluate (/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/zombie/lib/document.js:253:75)\n ... 

… что делает вид, что проблема с соединением / кодом состояния 0 решена с помощью этого wait() . Однако есть еще одна проблема: один из классов JavaScript, который использует страница, не может быть найден, а программа выйдет из строя – и что еще хуже, в фоновом режиме происходят процессы mink , и пока я их не kill , я не могу снова запустить сценарий , Но я отправлю еще один вопрос для этого … и сделал это, здесь: PHP Mink / Zombie – обработка зависающих процессов после фатального исключения?