我编写了一个脚本,通过发送 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
对象的状态。您可以看到下面的输出。
我在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 = bless( { '.parameters' => [ 'thisvar', 'anothervar', 'oh' ], '.crlf' => ' ', '.globals' => { 'DEBUG' => 0, 'NO_UNDEF_PARAMS' => 0, 'NO_NULL' => 1, 'FATAL' => -1, 'USE_PARAM_SEMICOLONS' => 0, 'PARAM_UTF8' => 0, 'DISABLE_UPLOADS' => 1, 'USE_CGI_PM_DEFAULTS' => 0, 'NPH' => 0, 'POST_MAX' => 102400, 'HEADERS_ONCE' => 0 }, 'anothervar' => [ 'anothervalue' ], 'oh' => [ 'lala' ], 'thisvar' => [ 'thatvalue' ], '.fieldnames' => { 'anothervar' => 1, 'oh' => 1, 'thisvar' => 1 }, '.header_printed' => 1 }, 'CGI::Simple' );
关于perl - 如何在 Windows 上使用 Perl 读取 https 页面的内容,而不安装 OpenSSL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10333823/