重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

いつも助け手いただいており,ありがとうございます。
ある団体のお手伝いでHPをいじっております。
基本,既製のスクリプトを改造しながら,あれこれやっておりますが,
新たに作る必要がうまれ,あれこれ始めましたが,open にてつまづきました。
perlについては,初心者のレベルだと思います。

やってることは単純なことだと思うのですが,下記内容のhtmlファイルを開くことです。

 ファイル名 test.html
中身↓
 <!DOCTYPE html>
<html>
<head>
<title>ページタイトル</title>
</head>
<body>
<p>うまく動くでしょうか。</p>
</body>
</html>

このファイルを開くのに,
ファイル名 app.cgi
中身↓
#!/usr/bin/perl

open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
my @tmp=<IN>;
close (IN); #ファイルハンドルを閉じる
print @tmp;
exit;

だと500のサーバーエラーになりますが,下記のようにprint(・・・・)を入れるときちんと実行できます。

ファイル名 app.cgi
中身↓
#!/usr/bin/perl

print "Content-type: text/html\n\n";
open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
my @tmp=<IN>;
close (IN); #ファイルハンドルを閉じる
print @tmp;
exit;

なぜprintを入れるとエラーにならないのか分かりません。テキストファイルを開くときは,
printを入れなくてもひらけるようですが,この辺の違いがよく分かりません。

アドバイスいただけるとありがたいです。

質問者からの補足コメント

  • >ファイル名 app.cgi
    >中身↓
    >#!/usr/bin/perl

    >print "Content-type: text/html\n\n";
    >open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
    >my @tmp=<IN>;
    >close (IN); #ファイルハンドルを閉じる
    >print @tmp;
    >exit;

    この部分ですが,下記,▼~▲の間が,app.cgiの内容ということです。

    #!/usr/bin/perl
    print "Content-type: text/html\n\n";
    open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
    my @tmp=<IN>;
    close (IN); #ファイルハンドルを閉じる
    print @tmp;
    exit;

      補足日時:2024/12/22 23:25
  • No1さんのご指摘のように,このスクリプトは,あるスクリプトのぱくりです。
    ただ,パクりでも,そのぞれの行についての役割は理解して,いるつもりです。
    #以下のコメントについては,実行には影響にないので,削除しなかっただけです。
    app.cgi から test.html を開くことをやりたかったのです。
    test.htmlの中身も掲載したように,最低限のものにしたつもりです。

      補足日時:2024/12/22 23:33
  • きちんと検証できていなかったみたいで,
    close (IN); 
    print @tmp
    を入れ替えても,エラーでした。

    No.2の回答に寄せられた補足コメントです。 補足日時:2024/12/23 00:12
  • 大きな思い違いをしていたようで,ヘッダー情報=htmlファイルの<head>の部分,
    と思ってたようです。No4さんのご紹介くださったHPにて,理解できました。
    おかげで,print "Content-type: text/html\n\n";がないとエラーになることの理解
    もできました。ベストアンサーにさせていただきます。

    No.5の回答に寄せられた補足コメントです。 補足日時:2024/12/23 00:35

A 回答 (5件)

普段意識することはありませんが。


htmlファイルに書いたものがそのまま送信されているのではありません。

リクエストを送ると、受け取ったサーバーは URLを解釈してデータを送り返してきます。
このとき送られてくるデータには「ヘッダー」が付けられます。
ヘッダーはテキストで書かれた情報であり、改行だけの行で本体データと区切られます。


例えば
http://〜/test.html
 とブラウザに入力したら、受けとったサーバーは
 該当するファイルを読み込み、ヘッダーを付けて
Content-type: text/html
(その他のヘッダー)
(改行だけの行)
<!DOCTYPE html>
(以下test.htmlの内容)
 というデータにして送り返します。

受けとったブラウザはヘッダーと本体データを分けて処理します。
例) Content-type: text/html はHTMLファイルなので、本体データをHTMLと解釈してブラウザで表示する。



CGIというのは、このHTTPサーバーの
「該当するファイルを読み込み、ヘッダーを付けて送信」
という動作のかわりに
「該当するプログラムを実行し、出力をそのまま送信」
という動作をするものです。ファイルのときにあった「ヘッダーを付けて」の部分はプログラムに組込まれています。
ヘッダーが不正なものはエラーになります。


print "Content-type: text/html\n\n";
はこのヘッダーを出力するものです。
削除すると全体として「不正なデータを出力するプログラム」になってしまうためにエラーになります。

openとは関連はありません。


なお、そのプログラムは「該当するファイルを読み込み、ヘッダーを付けて送信」というのをCGIで書いたものです。
この回答への補足あり
    • good
    • 0
この回答へのお礼

詳しい解説ありがとうございます。

print "Content-type: text/html\n\n";
がないと,「不正なデータを出力するプログラムになる」
ということ理解できました。

ただ,open には関係ないとのことですが,
読み込んだデータを出力する print と close  を逆にすると,エラーがでなくります。
このあたりは,どう,解釈すればいいのでしょうか。

それほど多くのものためしたのではないのですが,少なくとも,正常に表示されている,html ファイルを,2,3,読み込んでみましたが,読み込みに使った,質問に掲載したスクリプトでは,print部分なしでは,エラーになります。
ということは,正常に表示されているファイルは,表示に使っているスクリプトのどこかで,
"Content-type: text/html\n\n";
を記述して,送信しているのでしょうか

それから,気になる部分ですが,冒頭に,
http://〜/test.html
とあります。今回質問に掲載させていただいたのは,
http://〜/app.cgi
とcgiを呼び出しています。
この辺も,関係あるのでしょうか。

アドバイスいただければありがたいです。

お礼日時:2024/12/22 17:54

こんにちは



横からですが・・

No3様が指摘していらっしゃる「ヘッダー」に関して、少し調べてみるのが宜しいかと思います。
https://allabout.co.jp/gm/gc/433673/2/
http://sak.cool.coocan.jp/w_sak3/doc/sysbrd/pe_k …
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

私も,エラーの原因は,ヘッダー がらみかなとは推測していたのですが,

質問に掲載した,表示使用としているhtmlファイルにも最低限の情報は書かれているように思うのですが。

No2 さんの解答のように,close と 最後の print を逆にすると,
最初の print が無くてもエラーになりません。

この辺が,どうしてなのか,という疑問が残ります。

お礼日時:2024/12/22 17:19

No.1です。



> print の記述のある説明をみていませんでした。

print文は指定された内容を標準出力するだけです。
そうではく

> print "Content-type: text/html\n\n";

は具体的に何を書き出しているかです。
試しに

print "Content-type: text/html\n";

としてみましょう。\n\nではなく、\nとしてみるのです。
どうなりますか?
このprint文で出力しているのはHTTPヘッダーのうちのContent-type行です。
では、test.htmlファイルの中身は何でしょう?
そういう最も基本的なHTTPのデータ構造を理解していないので「このprint文の有無で何でエラーになったりならなかったりするの?」となるのでしょう。
プログラムの表面ばかり見ていて、プログラムが動く環境とプログラムが何をしていいるかを理解していないから起きている問題だと当方は思います。

ではでは。
    • good
    • 1
この回答へのお礼

何度もアドバイスありがとうございます。

繰り返し,になりますが,質問するにあたって,

test.html

の内容も最初の質問に記載しておりますので,test.html中身は何でしょうと聞かれても,返答にこまるのですが。
私としては,test.htmlの中身も理解した上での質問だと思っております。
付け加えると,単なるテキストファイルだとエラーになりません。
この辺も含めてアドバイスをいただけるとありがたいです。

お礼日時:2024/12/22 16:27

おそらく、


close (IN); と
print @tmp; の順番が逆なんだと思うが、

print "Content-type: text/html\n\n"; を書き足すと
なぜエラーにならないのかは、サッパリ解らない。
この回答への補足あり
    • good
    • 0
この回答へのお礼

早速の解答ありがとうございます。アドバイの通り,
直して,確かめてみました。

#!/usr/bin/perl

open (IN,"test.html");
my @tmp=<IN>;
print @tmp;
close (IN); #ファイルハンドルを閉じる

exit;

で,実行してみましたら,エラーはでませんでした。

close (IN); はファイルハンドルを閉じるだけなので,その後でprintしても,配列にとりこまれた@tmpの内容は保持されると思ってましたが,違うんでしょうかね。

>print "Content-type: text/html\n\n"; を書き足すと
>なぜエラーにならないのかは、サッパリ解らない。
の理由を知りたいと思っての投稿です。

openの前のprintがなくても,
テキストファイルのopenだと,close の後にprintしてもエラーにならないようです。

お礼日時:2024/12/22 15:59

> このファイルを開くのに,


>ファイル名 app.cgi
> 中身↓

えっと。。。
この文章の意味をり合い出来ません。


> #!/usr/bin/perl

これはPerlで記述するCGIプログラムの頭に記すPerlの実行プログラムが置かれている場所です。


> open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む

実際にオープンしようとしているファイル名(test.html)とコメントにあるファイル名(index.html)が一致していません。
細かい事ですが。。。
また、やっていることは「index.htmlというHTMLファイルを読み込む」ではなく「test.htmlファイルのオープン」です。
更に言えば、ファイルのオープンをしていることはプログラムソースを見ればわかるので、コメントして必要なのはtest.htmlはどういうファイルなのかの説明です。


> だと500のサーバーエラーになりますが,

HTTPの500番のエラーの意味は確認されましたか?
これはWebサーバー上でのCGIプログラムの実行で何らかのエラーが発生したため、実行中のCGIプログラムの処理を打ち切った・・・つまりこれ以上このCGIプログラムを実行することが出来なくなったというものです。


で、ですね。。。
質問者様はご自身が扱っているプログラムが何をしているかを理解されていないのだと思います。
つまり「自分がやりたいことをやっていると思われるプログラムを見つけて来て、その中身が具体的に何をどういう手順で処理してやりたいことをじちゅ減しているかを理解せずに使っている」のでしょう。
まずやらなければならないことは、以下の4行の1行、1行の意味を理解することです。

> open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
> my @tmp=<IN>;
> close (IN); #ファイルハンドルを閉じる
> print @tmp;

なお、その際、test.htmlの中身も理解しましょう。
そうしないとこのプログラムはアクセスして来たWebブラウザに対してどういう内容のHTMLを送出しているかがわからないからです。

ちなみに、このプログラムはどこかからパクって来たものである場合、パクリ元のプログラムは質問者様の下でちゃんと動いていますか?
動いているとすれば、test.htmlに当たるファイルの中身はどうなっていますか?

全てが“おまじない”のように動いる状況なのでしたらPerlであれ何であれプログラミングをやっているという状態ではないので、ちゃんと基本的な理屈を理解されることです。
CGIプログラムという動的コンテンツを扱われているわけですが、そもそも基本中の基本である静的コンテンツはどう作られていているかや、HTTPの通信ではコンテンツのHTML本文の前にどういうHTTPヘッダーを付けなければならないといったことを理解しましょう。
それがわかれば・・・

> print "Content-type: text/html\n\n";

の有無でなぜ500エラーになったり正常に実行でいたりするのかを近い出来ます。

参考まで。
    • good
    • 0
この回答へのお礼

早速の解答ありがとうございます。
私のやり方として,先達の書いてくださったスクリプトを参考に,
少しずつ自分なりに改変して,動く物を積み重ねていく,
というやり方で,覚えております。

今回,掲載した#以下のコメントと,やろうとしていることが一致してないということは,理解しています。
スクリプトの実行に差し支えないところなので,そのまま残してしまってました。


>動いているとすれば、test.htmlに当たるファイルの中身はどうなっていますか?
これも,test.html の中身として,質問に掲載させていただいております。

>えっと。。。
>この文章の意味をり合い出来ません。
ですが,ファイルに記載されている中身内容を記述を,説明したつもりです。

私がアドバイスいただきたかったのは,print のあるなして,
なぜ,サーバーのイターナルエラーがでたりしなかったりするのかというこです。

open の方法で,あちこちのHPを見ましたが,openの前に,
print の記述のある説明をみていませんでした。
テキストファイルだと,うまくいくのに,htmlだとうまくいかない,その辺のアドバイスがほしかったのですが。

お礼日時:2024/12/22 14:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A