2

友達、
私はPerlを使ってWebブラウザに画像を表示するための解決策をWebで探していましたが、私にとってうまくいくものは何も見つかりませんでした。
私は次のような可能な解決策を試しました:
Perlで画像を表示する方法
画像データを出力
するスクリプトから画像を返すが、
私が行っていることではどれも機能しません。クライアントによる画像へのアクセスを拒否し(または、画像ファイルを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

}

モジュールの1つ:

sub return_page_content {

return <<HTML;
<html>
  <body>
    <img src="GET IMAGE HERE..." />
  </body>
</html>
HTML
}

一時ディレクトリの場所にイメージのコピーを作成することだけを考えましたが、それでは、イメージをクライアント側からアクセスできないようにするという目的全体が無効になるようです。
考えられる解決策は画像を生成しません。ここからどこへ行けばいいのかわからないので、ここの誰かにアイデアを出してもらいたいです。どうもありがとう!
追加情報が必要な場合はお知らせください。これは多くの人にとって有益だと思います。私は少なくとも願っています;-)

4

4 に答える 4

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

これについて詳しくは、上記のリンク先のサイトをご覧ください。

お役に立てば幸いです。

于 2012-12-13T03:21:37.737 に答える
2

これが機能しなかった理由は、標準の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スクリプトとして実行するように指示します。その時点で、以前とは異なり、適切に情報を提供します。

これは最も安全な方法ではありませんが、正しい方向に進むことができます。

于 2012-12-14T18:24:20.880 に答える
1

あなたが見つけたリンク(最初のものを除く)はそれを行う方法を説明しています、私はあなたが画像配信することとその上にimgタグが付いたhtmlファイルを配信することの違いに混乱していると思います。ブラウザがhtmlファイルを解析しているときにimgタグが検出されると、タグ内のsrc urlを取得し、追加のgetリクエストを行うことに注意してください。

curl、wiresharkなどを使用して、画像のリクエストから生の出力をキャプチャしてみてください。結果は、作成しようとしているものです。コンテンツタイプのhttpヘッダーを返し、その後にバイナリイメージデータを返すだけです。

この例をもう一度見て、random_file subを削除し、次の行を置き換えます。

    my $image = random_file( IMAGE_DIRECTORY, '\\.(png|jpg|gif)$' );

これとともに:

    my $image = "path to an image file accessible by www-user";

うまくいけば、それが機能し、それが何をしているのかを理解したら、次に何をする必要があるのか​​がわかるでしょう。

于 2012-12-13T02:53:35.400 に答える
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);
于 2012-12-13T03:46:56.370 に答える