使用Win32::IE::Mechanize。如今,所有 Windows 系统都有某些版本的 Internet Explorer(尽管在某些系统上,管理员可能会阻止功能)。
您也可以使用 Win32::OLE 来“手动”驱动 IE ;-)
以下代码在我古老的 Windows XP SP3 系统上“工作”。我不确定它是否适用于 Vista 或 Windows 7 UAC。 showcgi.pl 只是转储$cgi 对象的状态。你可以看到下面的输出。
我会在my blog post 中更详细地解释发生了什么。
我没有设置用于测试的 SSL 服务器,但请让我知道在这些修改后脚本是否可以工作。
#!/usr/bin/env perl
package My::Poster;
use strict; use warnings;
use Const::Fast;
use Try::Tiny;
use Win32::OLE;
use Win32::OLE::Variant;
local $Win32::OLE::Warn = 3;
# http://msdn.microsoft.com/en-us/library/aa768360%28v=vs.85%29.aspx
const my %BrowserNavConstants => (
navOpenInNewWindow => 0x1,
navNoHistory => 0x2,
navNoReadFromCache => 0x4,
navNoWriteToCache => 0x8,
navAllowAutosearch => 0x10,
navBrowserBar => 0x20,
navHyperlink => 0x40,
navEnforceRestricted => 0x80,
navNewWindowsManaged => 0x0100,
navUntrustedForDownload => 0x0200,
navTrustedForActiveX => 0x0400,
navOpenInNewTab => 0x0800,
navOpenInBackgroundTab => 0x1000,
navKeepWordWheelText => 0x2000,
navVirtualTab => 0x4000,
navBlockRedirectsXDomain => 0x8000,
navOpenNewForegroundTab => 0x10000,
);
sub new {
my $class = shift;
my $self = bless {} => $class;
$self->init;
return $self;
}
sub ie {
my $self = shift;
my $ie = shift;
return $self->{ie} unless defined $ie;
$self->{ie} = $ie;
return;
}
sub init {
my $self = shift;
$self->ie(
Win32::OLE->new(
'InternetExplorer.Application',
sub {
my $ie = shift;
try { $ie->Quit if $ie } catch { warn "$_\n" };
},
)
);
return;
}
sub post {
my $self = shift;
my ($url, $data) = @_;
my $ie = $self->ie;
my $flags = $BrowserNavConstants{navNoHistory} |
$BrowserNavConstants{navNoReadFromCache} |
$BrowserNavConstants{navNoWriteToCache} |
$BrowserNavConstants{navEnforceRestricted} |
$BrowserNavConstants{navNewWindowsManaged} |
$BrowserNavConstants{navUntrustedForDownload} |
$BrowserNavConstants{navBlockRedirectsXDomain}
;
# $postdata should also be converted to bytes here
# I don't remember the right way to do it, and it works for ASCII
# so it should be good enough for now.
my $postdata = join '&', map join('=', @$_), @$data;
my $vPostData = Variant(VT_ARRAY|VT_UI1, length $postdata);
$vPostData->Put($postdata);
# http://msdn.microsoft.com/en-us/library/aa752133%28v=vs.85%29.aspx
$ie->Navigate(
$url,
$flags,
'_self',
$vPostData,
"Content-Type: application/x-www-form-urlencoded\015\012",
);
while ($ie->{ReadyState} != 4) {
sleep 1;
}
return $ie->Document->documentElement->innerHTML;
}
sub DESTROY {
my $self = shift;
try { $self->ie->Quit } catch { warn "$_\n" };
return;
}
package main;
use strict; use warnings;
my $poster = My::Poster->new;
my $html = $poster->post(
'http://test.localdomain:8080/cgi-bin/showcgi.pl',
[
[ thisvar => 'thatvalue', ],
[ anothervar => 'anothervalue', ],
[ oh => 'lala', ],
],
);
print $html if defined $html;
输出:
$VAR1 = 祝福({
'.参数' => [
'thisvar',
'另一个',
'哦'
],
'.crlf' => '
',
'.globals' => {
'调试' => 0,
'NO_UNDEF_PARAMS' => 0,
'NO_NULL' => 1,
'致命' => -1,
'USE_PARAM_SEMICOLONS' => 0,
'PARAM_UTF8' => 0,
'DISABLE_UPLOADS' => 1,
'USE_CGI_PM_DEFAULTS' => 0,
'NPH' => 0,
'POST_MAX' => 102400,
'HEADERS_ONCE' => 0
},
'另一个变量' => [
'另一个价值'
],
'哦' => [
'拉拉'
],
'thisvar' => [
'那个值'
],
'.fieldnames' => {
'另一个变量' => 1,
'哦' => 1,
'thisvar' => 1
},
'.header_printed' => 1
}, 'CGI::Simple' );