2012-12-13 35 views
1

朋友,
我一直在網上尋找一種解決方案,用Perl向Web瀏覽器顯示圖像,並且沒有發現適合我的東西。
我試過可行的解決方案,如:
How To Display an Image with Perl
Outputting Image Data
Return an Image From a Script
沒有它適用於我在做什麼。我想拒絕客戶端對圖像的訪問(或者甚至只是將圖像文件從www根目錄中移出)並將其放在服務器端。
下面是我在做什麼的例子:

在我的主要perl的文件:Perl CGI將圖像顯示到瀏覽器的文件

... 
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 
} 

我想過剛剛創建將圖像複製到臨時目錄位置,但這似乎會破壞將圖像保留在客戶端訪問之外的整個目的。
可能的解決方案不會生成圖像。我不知道該從哪裏出發,所以我希望這裏有人有一個想法。非常感謝!
請讓我知道如果我需要提供更多的信息。我覺得這對很多人都有好處。我希望至少;-)

回答

1

那麼,事實證明,這是不工作的原因是因爲我完全忘了我不使用標準cgi_bin目錄中的CGI操作。相反,我使用.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腳本。在那個時候,它恰如其分地提供了信息,而不像以前那樣。

請注意,這不是最安全的方式,但它使我朝着正確的方向前進。

1

您發現鏈接(除了第一個)描述瞭如何做到這一點,我想你是剛與之間的差異提供的圖像提供一個HTML文件迷茫一個img標籤。請記住,當瀏覽器解析一個html文件並遇到一個img標籤時,它會在標籤中使用src url併爲其提供額外的獲取請求。

嘗試捕捉從請求原始輸出使用捲曲,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"; 

希望,一旦你的工作,並瞭解它的做,你會知道你下一步需要做什麼。

+0

我已經完成了你建議的隨機文件名。我會看看Wireshark告訴我的。謝謝回覆! – Thumper

+0

嗯...它最終刪除圖像(零KB文件被留下)。我覺得這可能會開放一點。 – Thumper

2

對於一個簡單的「發送文件到瀏覽器的解決方案」,只是給瀏覽器正確的頭(讓瀏覽器知道什麼是未來),然後打開你的圖像和打印的內容輸出到標準輸出。

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:-'); 

你可以閱讀更多關於這上面鏈接在網站上。

希望有所幫助。

+0

本例中不需要Image :: Magick。只需編寫內容。 – jordanm

+0

一旦我有機會,我會看第一部分。使用Macick是不可能的,因爲它是幾MB大。我寧願不要在網絡服務器上託管它 – Thumper

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); 
+0

這一個也沒有爲我工作,但我發現我的問題。 – Thumper