是否可以使用PERL在浏览器中呈现pdf?我所拥有的是一个将呈现的pdf二进制文件发送到perl的flash应用程序。 pdf是从AlivePDF生成的。
#!C:\Perl\bin\perl.exe
##
BEGIN { $ENV{PATH} = ''; delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; }
use strict;
use warnings;
no warnings qw (redefine closure);
use CGI;
my $CGI = new CGI();
#name=generated.pdf&method=inline these are passed via the URL and are in the environmental variable QUERY_STRING
my %nv_pairs = map{my @tmp = split(/=/,$_);$tmp[0] => $tmp[1] }split(/&/,$ENV{QUERY_STRING});
my $name = $nv_pairs{name};
my $method = $nv_pairs{method};
#Raw Data is stored in the POST Parameter POSTDATA
my $pdf = $CGI->param('POSTDATA');
print "Content-Type: application/pdf\r\n";
print "Content-Length: " . length($pdf) . "\r\n";
print "Content-Disposition :$method\n\n";
print $pdf;
问题是我想实际呈现pdf的样子。我可以保存该二进制代码并在Adobe Reader中手动打开它并正确呈现。
我希望它能在浏览器中呈现,但我不知道如何实现它。
目前输出(浏览器显示的内容)如下所示:
Content-Type: application/pdf
Content-Length: 432785
Content-disposition:inline; filename="test.pdf"
%PDF-1.5
1 0 obj
<</Type /Pages
/Kids [3 0 R 5 0 R]
/Count 2>>
endobj
3 0 obj
<</Type /Page
/Parent 1 0 R
/MediaBox [0 0 612.00 792.00]
/Resources 2 0 R
这只是显示文件的一部分,但我希望这会有所帮助。我不希望代码显示,我希望它看起来像图形。如果我下载此文件,并将扩展名更改为.pdf,则效果非常好。
答案 0 :(得分:0)
您需要添加以下HTTP标头
print "Content-Transfer-Encoding: binary\n";
以下是我正在阅读pdf文件并显示它:
use strict;
use warnings;
my $file = "discover.pdf"; # a pdf I happen to have
my $pdf;
open (my $fh, $file);
binmode $fh; # set the file handle to binary mode
while (<$fh>){ $pdf .= $_; } # read it all into a string;
close ($fh);
showPdf($pdf); # call the display function
sub showPdf {
my $pdf = shift;
my $file = shift || "new.pdf"; # if no name is given use this
my $method = shift || "Content-disposition:inline; filename='$file'"; # default method
my $size = length($pdf);
print "Content-Type: application/pdf\n";
print "Content-Length: $size\n";
print "$method\n";
print "Content-Transfer-Encoding: binary\n\n"; # blank line to separate headers
print $pdf;
}
可以将相同的功能添加到原始代码中,并且应该像这样工作:
#!C:\Perl\bin\perl.exe
##
BEGIN { $ENV{PATH} = ''; delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; }
use strict;
use warnings;
no warnings qw (redefine closure);
use CGI;
my $CGI = new CGI();
#name=generated.pdf&method=inline these are passed via the URL and are in the environmental variable QUERY_STRING
my %nv_pairs = map{my @tmp = split(/=/,$_);$tmp[0] => $tmp[1] }split(/&/,$ENV{QUERY_STRING});
my $name = $nv_pairs{name};
my $method = $nv_pairs{method};
#Raw Data is stored in the POST Parameter POSTDATA
my $pdf = $CGI->param('POSTDATA');
showPdf($pdf, $name, $method);
sub showPdf {
my $pdf = shift;
my $file = shift || "new.pdf"; # if no name is given use this
my $method = shift || "Content-disposition:inline; filename='$file'"; # default method
my $size = length($pdf);
print "Content-Type: application/pdf\n";
print "Content-Length: $size\n";
print "$method\n";
print "Content-Transfer-Encoding: binary\n\n"; # blank line to separate headers
print $pdf;
}
答案 1 :(得分:0)
我没有在请求正文中创建PDF的Flash应用程序,但我根据具有相同响应标头的静态资源的输出验证了它。 Content-Disposition
是至关重要的。这是在Konqueror中使用Okular KPart进行测试并且有效,我完全希望其他浏览器/插件组合也能正常工作。
#!/usr/bin/perl -T
# ↑↑↑↑↑
# on Windows you can just write …
#!perl -T
# … instead, using the Unix shebang however does no harm
use strict;
use warnings FATAL => 'all';
use CGI qw();
use IO::File qw();
# delete @ENV{qw(BASH_ENV CDPATH ENV IFS PATH)};
# ↑↑↑↑↑
# Cleaning path is required for taint-checked programs
# that want to run other programs. It does not affect anything here,
# so I commented it out.
my $c = CGI->new;
# untaint data coming from outside
my ($name) = defined $c->url_param('name') ?
$c->url_param('name') =~ /\A ([a-zA-Z_-]{1,40}\.pdf) \z/msx : ();
my ($method) = defined $c->url_param('method') ?
$c->url_param('method') =~ /\A (attachment|inline) \z/msx : ();
die 'invalid parameters' unless $name or $method;
# FIXME: untaint blindly because I don't know how to validate PDF
my ($pdf) = $c->param('POSTDATA') =~ /(.*)/msx;
STDOUT->binmode(':raw');
STDOUT->print($c->header(
-Content_Type => 'application/pdf',
-Content_Length => length($pdf),
-Content_Disposition => qq($method; filename="$name"),
));
STDOUT->print($pdf);
请注意,您是mixing GET and POST parameters。学习如何编写安全的CGI程序。