2014-07-24 47 views
1

我使用WWW::Mechanize自動將'訂單'放入我們供應商的門戶(經許可)。通過填寫相關表單域和正常情況,這非常簡單。WWW :: Mechanize - 如何在不影響頁面堆棧和/或當前HTML :: Form對象的情況下進行POST?

但是,門戶網站已經考慮到了支持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)

如果我注入了新的形式(在action引用/delete.do)到DOM和使用submit然後機甲對象將不從前面的redirects to page #X步驟構建的對象更長。

如果我剛剛使用back()從那一點,這是否使另一個GET到服務器? (或只是使用從頁面堆棧的前值?)

方法(B)

如果我只是用從LWP :: UserAgent的繼承了post()方法將POST發送到/delete.do我得到一個安全錯誤 - 我想這不是使用由WWW :: Mechanize設置的cookie jar。

有一些規範的方法,使「出來的帶外」 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()的機械化對象,填寫表格,並提交 它!

{ 
    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。例如:

{ 
    my $mech = $mech->clone(); 
    $mech->post(....); 
} 

但是,當然最好是爲此製作sub。

+0

嗯,它使用相同的餅乾罐。優秀。 –

相關問題