友
我一直在网上寻找一个解决方案,用Perl向Web浏览器显示图像,并且发现没有什么对我有用。
我尝试过可能的解决方案,例如:
How To Display an Image with Perl
Outputting Image Data
Return an Image From a Script
并且它都不适用于我正在做的事情。我想拒绝客户端访问图像(或者甚至只是将图像文件放在www根目录之外)并将其放在服务器端。
这是我正在做的一个例子:
在我的主要perl文件中:
...
my $query = CGI->new();
sub main {
### This grabs page content from a module, depending on the page name.
### The module returns the HTML.
my $html = get_page('page', 'session');
### Perform any special conditionals here before printing the header...
print $query->header(some cookie/session data here);
print $html
}
在其中一个模块中:
sub return_page_content {
return <<HTML;
<html>
<body>
<img src="GET IMAGE HERE..." />
</body>
</html>
HTML
}
我想过只是在临时目录位置创建一个图像副本,但这似乎会破坏保持图像不受客户端访问的整个目的。
可能的解决方案不会生成图像。我不知道从哪里开始,所以我希望这里有人有个主意。非常感谢你!
如果我需要提供更多信息,请与我们联系。我觉得这对很多人都有好处。我希望至少; - )
答案 0 :(得分:3)
对于简单的“将文件发送到浏览器解决方案”,只需向浏览器发送正确的标题(让浏览器知道即将发生的事情),然后打开图像并将内容打印到STDOUT。
select(STDOUT); $| = 1; #unbuffer STDOUT
print "Content-type: image/png\n\n";
open (IMAGE, '<', '/image_outside_webroot/image.png');
print <IMAGE>;
close IMAGE;
一旦有效,请查看ImageMagick。你可以做各种动态,有趣的图像处理(调整大小,着色等)。
您的cgi脚本将包含如下所示的代码:
select(STDOUT); $| = 1; #unbuffer STDOUT
my $image = Image::Magick->new();
my $x = $image->Read(filename =>"/images_outside_web_root/image1.png");
#some manipulation of the image here
print "Content-type: image/png\n\n";
binmode STDOUT;
$x = $image->Write(.png:-');
您可以在上面链接的网站上阅读有关此内容的更多信息。
希望有所帮助。
答案 1 :(得分:1)
您找到的链接(第一个除外)描述了如何操作,我认为您只是对提供图像和提供html文件之间的区别感到困惑img标签就可以了。请记住,当您的浏览器解析html文件并遇到img标记时,它会获取标记中的src url并为其发出额外的get请求。
尝试使用curl,wireshark等从图像请求中捕获原始输出。结果是您想要尝试创建的内容。这只是返回内容类型http标头,然后是二进制图像数据的问题。
再看看this示例,并删除random_file子,并替换此行:
my $image = random_file( IMAGE_DIRECTORY, '\\.(png|jpg|gif)$' );
用这个:
my $image = "path to an image file accessible by www-user";
希望一旦你工作并了解它正在做什么,你就会知道接下来需要做什么。
答案 2 :(得分:1)
另一种方法是使用<img src="data:image/...,base64,...">
格式嵌入图像。
这会破坏浏览器缓存,对于非常大的图像来说并不是很好。但如果它更容易构建图像作为初始页面加载的一部分,或者您不希望通过文件系统管理/提供它们的麻烦,那么它很有用。
#!/user/bin/perl
use warnings; use strict;
use MIME::Base64 qw();
sub return_page_content {
my $image_type = shift;
my $image_data = shift;
my $image_base64 = MIME::Base64::encode($image_data);
$image_base64 =~ s{\n}{}g; # lose newlines
return <<HTML;
<html>
<body>
<img src="data:image/${image_type};base64,${image_base64}" />
</body>
</html>
HTML
}
my $image_path = "/tmp/test.jpg";
open(my $fh, '<', $image_path)
or die "unable to open file $image_path: $!";
binmode($fh);
my $image_data = do {local $/; <$fh>};
close($fh);
print return_page_content("jpeg", $image_data);
答案 3 :(得分:1)
嗯,事实证明这不起作用的原因是因为我完全忘记了我没有使用CGI超出标准的cgi_bin目录。相反,我使用.htaccess文件告诉服务器如何以及何时将根目录中的文件解释为cgi。
所以,这就是我最终在我的图像凹陷脚本中使用的内容:
imagedish.pm
use CGI;
my $cgi = new CGI;
open (IMAGE, 'logo.png');
my $size = -s "logo.png";
my $data;
read IMAGE, $data, $size;
close (IMAGE);
print $cgi->header(-type=>'image/png'), $data;
这就是诀窍,因为它应该从一开始就做,但在我的.htaccess文件中,我补充说:
<files imagedish.pm>
SetHandler cgi-script
</files>
这就是诀窍(好吧,那就是进入终端并运行chmod + x imagedish.pm以使其可执行)!当然接下来的步骤是额外的安全措施,但至少它现在正在运行! :-)
完整的解决方案:
mainfile:
!/usr/bin/perl
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI::Session qw/-ip-match/;
use DBI;
use strict;
use warnings;
# Variables
my $query = CGI->new();
my %vars = $query->Vars();
sub main {
my $p1 = $vars{p1};
$p1 = 'Home' if (!$p1);
my $html = get_page();
#I use this method in case we have multiple sessions
#I've omitted how I acquire the session, as this is not part of the solution ;-)
print $query->header(-cookie=>[$query->cookie($vars{p1}=>$session->id)]);
print $html;
}
sub get_page {
return <<HTML;
<!DOCTYPE HTML>
<html>
<head>
<title>Image Disher</title>
<link rel="shortcut icon" href="images/favicon.ico" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<div class="addentry">
<div class="iaddentry">
<form name="client" action="" method="POST">
<div class="form-header" action="">
<center>
<img src="imagedish.pm" width="305" alt=""/><br>
</center>
<br>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
HTML
}
main();
在这里,img标签查找源“imagedish.pm”,一旦找到它,.htaccess文件就会告诉它作为CGI脚本执行。在这一点上,它适当地剔除信息,而不是像以前那样。
请注意,这不是最安全的方法,但它让我朝着正确的方向前进。