我编写了一个脚本,它通过发送 POST 请求来读取 https 页面的内容,并将其转储到文本文件中。它在 Linux 下运行良好,在安装Shining Light OpenSSL后也可以在我的 Windows 机器上运行。但是客户说他们无法在他们的 Windows 机器上安装任何 exe,并要求提供替代解决方案。
我们这里有其他选择吗?也许一些代理接受 POST 请求,获取 https 内容并将其作为 http 传递?我知道很多一厢情愿的想法,但我只想在这里探索任何可能的选择。
我编写了一个脚本,它通过发送 POST 请求来读取 https 页面的内容,并将其转储到文本文件中。它在 Linux 下运行良好,在安装Shining Light OpenSSL后也可以在我的 Windows 机器上运行。但是客户说他们无法在他们的 Windows 机器上安装任何 exe,并要求提供替代解决方案。
我们这里有其他选择吗?也许一些代理接受 POST 请求,获取 https 内容并将其作为 http 传递?我知道很多一厢情愿的想法,但我只想在这里探索任何可能的选择。
使用Win32::IE::Mechanize。如今,所有 Windows 系统都有某些版本的 Internet Explorer(尽管在某些系统上,管理员可能会阻止功能)。
您也可以使用Win32::OLE来“手动”驱动 IE,可以这么说 ;-)
以下代码在我古老的 Windows XP SP3 系统上“工作”。我不确定它是否适用于 Vista 或 Windows 7 UAC。showcgi.pl
只是转储$cgi
对象的状态。你可以看到下面的输出。
我会在我的博文中更详细地解释发生了什么。
我没有为测试设置 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' );