Я использую WWW::Mechanize для автоматизации размещения заказов на портале нашего поставщика (с разрешения). Это довольно прямолинейно, если заполнить соответствующие поля формы и submit
ing, как обычно.WWW :: Mechanize - как POST, не влияя на стек страниц и/или текущий HTML :: объект формы?
Однако портал был построен с использованием JavaScript-совместимого клиента, и в результате были сделаны короткие сокращения; наиболее значительным сокращением, которое они взяли, является то, что по мере прохождения через «мастера» (серии форм) с обычными POSTS они требуют, чтобы вы «освободили» часть ресурсов на стороне сервера для «предыдущего шага мастера», выполнив AJAX POST , В псевдокоде:
GET page #1
fill the fields of page #1
POST (submit the form) --> redirects to page #2.
POST (ajax request to "/delete.do")
fill the fields of page #2
POST (submit the form) --> redirects to page #3.
POST (ajax request to "/delete.do")
fill the fields of page #3.
...
Что самый простой подход, чтобы сделать эти ajax request to "/delete.do"
запросы?
Я пытался ...
Appoach (A)
Если я впрыснуть новую форму (ссылающийся /delete.do
в action
) в DOM и использовать submit
тогда объект будет не механ дольше есть объект HTML::Form
, построенный с предыдущего этапа redirects to page #X
.
Если я просто использую back()
с этой точки, делает ли это еще GET
на сервер? (Или это просто используя предыдущие значения из стека страницы?)
подход (B)
Если я просто использовать post()
метод, унаследованный от LWP :: UserAgent, чтобы отправить сообщение в /delete.do
я получаю ошибка безопасности - я предполагаю, что не использует кувшин cookie, который был настроен WWW :: Mechanize.
Есть некоторые канонический способ сделать «вне зоны» POST, что:
- ли использование/обновление WWW :: механизировать в куков
- ли следовать перенаправляет
- не ли изменить стек страницы
- не изменяет текущий HTML :: объект Form
UDPATE: Для тех, кто пытается повторить решение, предложенное gangabass, вы на самом деле нужно:
(1) Подкласс
WWW::Mechanize
, перекрываяupdate_html
таким образом, что новое содержание может быть введен в HTML по запросу.Это содержимое, как правило, обрабатывается
HTML::Form::parse()
. Приоритет переопределения должен изменить первый несамостоятельный параметр$html
перед вызовом первоначальной реализации и возвратом результата.package WWW::Mechanize::Debug; use base 'WWW::Mechanize'; sub update_html { my ($self,$html) = @_; $html = $WWW::Mechanize::Debug::html_updater->($html) if defined($WWW::Mechanize::Debug::html_updater); return $self->SUPER::update_html($html); } 1;
(2) В основной программе, использовать
WWW::Mechanize::Debug
согласноWWW::Mechanize
use WWW::Mechanize::Debug; my $mech = WWW::Mechanize::Debug->new;
(3) Инжектируйте HTML формы, которые должны быть
submit()
-е изд.{ my $formHTML = qq| <form action="/delete.do" method="POST" name="myform"> <!-- some relevant hidden inputs go here in the real solution --> </form> |; local $WWW::Mechanize::html_updater = sub { my ($html) = @_; $html =~ s|</body>|$formHTML</body>|; }; # Load the page containing the normal wizard step content. $mech->get($the_url); # This should how have an extra form injected into it. }
(4) В новой области
clone()
объекта Mechanize, заполнить форму и представить его!{ my $other = $mech->clone; my $myform = $separate->form_name('my_form'); $myform->field('foo' => 'bar'); # fill in the relevant fields to be posted $myform->submit; }
(5) Продолжайте использовать исходный объект механизировать, как будто это подчинение формы никогда не произошло.
Ах, и он использует ту же самую кукурузу. Отлично. –