2014-07-24 3 views
1

Я использую 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) Продолжайте использовать исходный объект механизировать, как будто это подчинение формы никогда не произошло.

ответ

2

Вам нужен clone ваш объект Mech и сделать POST из клонированной версии. Кое-что вроде:

+0

Ах, и он использует ту же самую кукурузу. Отлично. –