我正在使用WWW::Mechanize自动将“订单”放入供应商的门户网站(获得许可)。通过填写相关的表单字段和submit
正常,这样做非常简单。
然而,该门户网站的构建考虑了一个支持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
,那么mech对象将不再构建HTML::Form
对象从上一个redirects to page #X
步骤开始。
如果我从那时起只使用back()
,是否会为服务器生成另一个GET
? (或者它只是使用页面堆栈中的先前值?)
方法(B)
如果我只是使用从LWP :: UserAgent继承的post()
方法将POST发送到/delete.do
我收到安全错误 - 我猜它没有使用已设置的cookie jar通过WWW :: Mechanize。
是否有一些规范的方法来制作“带外”POST:
UDPATE: 对于试图复制gangabass建议的解决方案的任何人,您实际上需要:
(1)子类
WWW::Mechanize
,覆盖update_html
,以便a 可以根据需要将新内容注入HTML。此内容通常由
HTML::Form::parse()
解析。该 override sub需要改变第一个非自身参数$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)注入需要
submit()
编辑的HTML表单。{ 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)继续使用原始的mechanize对象,就像该表单一样 提交从未发生过。
答案 0 :(得分:2)
您需要clone
您的Mech对象并从克隆版本进行POST。类似的东西:
{
my $mech = $mech->clone();
$mech->post(....);
}
但是,当然最好为此制作sub。