cgiからcgiを呼び出す方法2

このQ&Aのポイント
  • 【経緯】もともと単体で動作していたcgi Aに対して新たにcgi Bを作成し、cgi Bからcgi Aを呼び出したいのですが、うまくいきません。
  • 【新たな質問】(1) cgi A の画面は表示されましたが title は cgi B のままです。exec で cgi A が呼び出された時点で title は cgi A にならないのでしょうか? (2)いろいろなサイトに、呼び出し先に "Content-Type: text/html; charset=Shift_JIS\n\n" の記述があってはダメとの説明がありましたが、この記述がないと cgi Aにてデータを入力し、送信ボタンを押すと 500 Internal Server Error(malformed header from script. Bad header~) が表示されてしまいます。Content-Type の記述があれば、cgi A の送信ボタンを押すことによって入力したデータがDBに格納され、また、title も cgi A のタイトルが表示されます。
  • 【cgi A が呼び出された時点の画面イメージ】cgi B のタイトル Content-Type: text/html; charset=Shift_JIS cgi A のタイトル cgi A の入力項目 cgi A の送信ボタン
回答を見る
  • ベストアンサー

cgiからcgiを呼び出す方法2

先日「cgiからcgiを呼び出す方法」で質問させていただいたのですが、 その後の状況にて新たな質問をさせていただきます。 【経緯】 もともと単体で動作していたcgi Aに対して新たにcgi Bを作成し、 cgi Bからcgi Aを呼び出したいのですが、うまくいきません。  cgi A:アンケート回答フォームのようなもの  cgi B:認証フォーム(コードを入力してDB内のデータと一致したらcgi Aを呼び出したい) 【その後の状況】 exec("perl A.cgi"); とすることで cgi A の画面を表示することが出来ました。 【新たな質問】 (1) cgi A の画面は表示されましたが title は cgi B のままです。  exec で cgi A が呼び出された時点で title は cgi A にならないのでしょうか? (2)いろいろなサイトに、呼び出し先に  "Content-Type: text/html; charset=Shift_JIS\n\n"  の記述があってはダメとの説明がありましたが、この記述がないと  cgi Aにてデータを入力し、送信ボタンを押すと  500 Internal Server Error(malformed header from script. Bad header~)  が表示されてしまいます。  Content-Type の記述があれば、cgi A の送信ボタンを押すことによって  入力したデータがDBに格納され、また、title も cgi A のタイトルが表示されます。 【cgi A が呼び出された時点の画面イメージ】  cgi B のタイトル  Content-Type: text/html; charset=Shift_JIS  cgi A のタイトル   cgi A の入力項目   cgi A の送信ボタン cgi A の送信ボタン(submit)を押すことによって、完全に cgi Aに制御が渡るということでしょうか? cgi A を呼び出した時点で完全に cgi A に制御を渡したいのですが、 どなたかアドバイスをお願いします。 cgi A の構成を変える必要があるようであれば、その当たりのアドバイスもお願いします。

  • CGI
  • 回答数5
  • ありがとう数8

質問者が選んだベストアンサー

  • ベストアンサー
noname#205944
noname#205944
回答No.5

横から失礼します。 一度認証して、LocationでちがうCGIを呼び出すのは 認証した意味がなくなると思うのですが・・ というのも、認証しないでいきなりCGI-Aを呼び出したらどうなります? 認証するということは、一度の処理ですべてを行わないと意味がなくなります。 なので、AとかBとかに分けないで1つにするのが初心者向けですよー もうちょっと理解が深まれば、CGI-Aをrequireして1つのCGIとしてあつかえることができます。 さらに簡単にするのなら、1つのCGI内でサブルーチンにして分けて処理を行う方向性が後々の変更のため そして、コード量を減らすことや なによりエラーをなくすためにはいい方法です。 例) 認証サブルーチン、DB問い合わせサブルーチン、アンケートフォームサブルーチン、アンケート受け取りサブルーチンetc そしてこれらを1つのCGIで処理するページングを行いたいのであれば、引数としてURLに含めるのが一般的です。 例) xxx/B.cgi?que=form (認証して入力用のアンケートフォームを表示するなど) xxx/B.cgi?que=input (認証してアンケートフォーム入力値を受け取り結果を表示するなど) 上記のように常に認証しないと、意味がなくなります。 それと、system関数やexec関数は同じプログラム言語を使うならお勧めできません。 環境によっては使えないことも多々ありますし、なによりコスト(サーバ負荷)とリスク(トンネル)が高いです。 この辺はもう少し言語に対する理解が深まってから手を出すべきです。(初心者に勧めるべきことではありませんよね) 横槍のようで何なんですけど、なんだか変な方向に行きそうなので、口を出してしまいました。

crescentmonkey
質問者

お礼

ご指摘ありがとうございます。 >認証しないでいきなりCGI-Aを呼び出したらどうなります? この点はいろいろなサンプルを参考に、HTTP_REFERERを意識しておりました。 >なので、AとかBとかに分けないで1つにするのが >初心者向けですよー >もうちょっと理解が深まれば、CGI-Aをrequireして >1つのCGIとしてあつかえることができます。 requireも頭の片隅には残してあります。 ご指摘の通り、他にもアドレス登録フォームやメール送信フォームなどが存在しており、全体を通してDBエラー処理など共通ロジックが個々のプログラムに存在している点は無駄だなぁと感じておりました。 まずは1つのプログラムが動くようになってから全体を通して最適化して行こうかなと。 今回もAとBは1本化します。 ありがとうございました。

その他の回答 (4)

  • ralf124c
  • ベストアンサー率52% (232/446)
回答No.4

perl歴9日でここまでやれるとは驚きです。 わたくしなどこの辺まで来るのにもっとかかったように思います。 皆さんが回答されたことを簡単にまとめてみます。 単純なサンプルコードとしては -------------------------------------------------- ## 認証コードの入力 my $sPWC = '認証コード'; my $sDBC = 'DBのコード'; ## 入力されたコードとDB内のコードの突き合わせ if($sPWC eq $sDBC){  ## 一致したらAを呼び出す  print "Location: http://www.hoge.jp/CGI_A.cgi\n\n"; }else{  print "Content-type: text/plain\n\n";  print "認証エラー\n"; } -------------------------------------------------- となります。 HTTPヘッダはブラウザを制御する命令です。 「Content-type」とくればこのあとデータが何らかの形式できますぜという命令ですし 「Location」とくればブラウザのアドレスにこの後のデータを入れてアクセスしますぜという命令です 改行が2回連続で来ればヘッダは終わりになります。 HTMLの出力はLocationで呼び出されたCGI_A.cgiが出力するように作ります。 もちろんそのときは「Content-type: text/html\n\n」をまず出力してそのあとHTMLデータを出力させるようにします。 > 今の僕の知識レベルではA内で全て処理した方が良い気がしてきました。 そうした方がより効率的なのが直感でわかってらっしゃるんです。 認証が一致したらCGI_Aの処理を丸々おこなえば良いだけなんでAとBに分ける必要性はほとんどありません。 蛇足ですが  execやsystemなどで呼び出したプログラムはCGIプログラムの「子」になります。  CGIそのものはWebサーバによって呼び出された「子」なのですが、上記プログラムは「孫」はWebサーバと直接つながりが無いのでCGIではなくなります。  関連を表現するとこんな感じでしょう。  [WEBサーバ]<=>(CGI)<=>[Perlプログラム]=>(exec)=>[Perlプログラム:結果待ち不要]  [WEBサーバ]<=>(CGI)<=>[Perlプログラム]<=>(system)<=>[Perlプログラム:結果待ち必要]  CGI(Common Gateway Interface)というのはインターフェースというぐらいですからプログラムを指すのではなくWebサーバとプログラムとの橋渡しする仕組みのことなのです。 ですからプログラムならCでもRubyでも標準入出力を持つ言語なら何でもいいのです。  execとsystemの違いも注目してください。  ご理解の助けになれば幸いです。

crescentmonkey
質問者

お礼

アドバイスありがとうございます。 もともとAが存在しており、後からBの機能を追加することになったので単純にBを新規で作成することにしました。 せっかく動いていたAに手を加えるのも何となく嫌だったので(^^;) 背中を押していただいたので、AとBを1本化します。 ありがとうございました。

回答No.3

1番目のものです。 まずは認証などを引き継がないでいいんですね。 つまり、直接Aが呼ばれても問題ないということで。 この場合もっとも簡単なのは、B内で処理が通ったあとに "Content-Type: text/html; charset=Shift_JIS\n\n" の代わりに "Location: http://xxxxxx/A.cgi\n\n" を出力するだけです。 事前に Content-type…の行を出力していたらダメですよ。 ブラウザ側から見て最初に渡される文字列が「Location: (A.cgiのURL)\n\n」になっている必要があります。 これで、ブラウザは「Aに飛ばないといけないんだな」ということがわかり、改めてAのほうを要求します。 ちょっと長いですが、参考URLのページが詳しいです。 ご参照ください。

参考URL:
http://www.rfs.jp/sb/perl/03/03.html
crescentmonkey
質問者

お礼

ありがとうございます。 参考URLにてサーバ側とクライアント側のイメージが深まりました。 B内では ・認証コードの入力 ・入力されたコードとDB内のコードの突き合わせ ・一致したらAを呼び出す ということをやりたいのですが、HTMLを出力しないでも 実現できるものなのでしょうか? 今の僕の知識レベルではA内で全て処理した方が良い気がしてきました。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

一応、前の回答に > あと、httpのヘッダが重複しないように注意。 と書いてあったんだけど..... CGIの基本として「サーバーでどんなことをしていようが、ブラウザが処理するのは、送られてきた成果物のみ」というのがあります。 CGIの出力は httpのヘッダ(複数行ある場合も) 改行のみの行 データ本体(ヘッダが content-type: text/htmlだったら htmlのデータ) という形式になっています。この形式でさえあれば、サーバー側で複数のプログラムで処理されていようが、1つのものとしてブラウザは処理します。 > 【cgi A が呼び出された時点の画面イメージ】 のようにブラウザで表示されるのは、そのように送られてきたからです。 逆に、 > Content-Type: text/html; charset=Shift_JIS > cgi A のタイトル ... だけが送られてきたら、URLがB.cgiだろうがC.cgiだろうが、cgi Aだけを指定したときと同じ表示になります。 対処法は 「exec までの間に cgi Bからは何も出力しない」 「初回や認証失敗等で単独でcgi Bを表示する場合だけ、httpヘッダも含めてcgi Bから出力する」 という様にcgi Bの処理の順番を入れ替えることです。 現在は cgi Bが出力したhttpヘッダ→httpのヘッダとして認識 cgi Bが出力したhtml(の一部?)→htmlのデータの一部として表示 cgi Aが出力したhttpヘッダ→「htmlのデータの一部として表示」 cgi Aが出力したhtml→htmlのデータの一部として表示 となっているようです。 > 呼び出し先に > "Content-Type: text/html; charset=Shift_JIS\n\n" > の記述があってはダメとの説明がありました これは、「ヘッダは常に呼び出し元で出力される」場合で、呼び出し先は「常に呼び出し先としてしか使用されない」場合です。 cgi Aは単独で使用されることがあるので、この出力は必要です。

crescentmonkey
質問者

お礼

分かり易い説明をありがとうございます。 >一応、前の回答に >> あと、httpのヘッダが重複しないように注意。 >と書いてあったんだけど..... すみません。httpヘッダの理解が乏しいまま、 execが通った喜びで先に進んでしまいました。 >「exec までの間に cgi Bからは何も出力しない」 >「初回や認証失敗等で単独でcgi Bを表示する場合だけ、 >httpヘッダも含めてcgi Bから出力する」 今回、事前に社員宛にメールで送信してある認証コードを cgi B から入力させ、DBに登録済のコードと一致したら cgi A を表示してアンケートを入力してもらう、 ということを実現したいのです。 今の僕の知識レベルでは、認証コードを入力するためのHTMLを出力する方法しか見いだせていないのですが、今のcgi AとB を1本に纏めてしまった方が簡単でしょうか? 引き続きご指南を宜しくお願いします。

回答No.1

これ、変更すべきはBのほうです。 Bで何らかの処理(ログイン処理など)を行っていると思いますが、それが成功した時に「『Aを読め』とブラウザに伝える」ことが必要になります。 ブラウザ側とサーバ側に分けて考えると理解しやすいです。 まずブラウザはBを呼び出しますよね。 Bの中でAをexecしたとしても、それはサーバ側の内部的な話。 ブラウザとしてはBを呼んでいるという認識ですから、そもそもAが呼ばれているかどうかなんてわかりません。 というわけで、Aから出力されたHTMLをブラウザに返していても、ブラウザから見れば「BというページのHTMLが送られてきた」としか認識できないんです。 なので、Bで処理が通った時点で、ブラウザに対して明示的に「Aを呼びなさい」という指示を与えてあげる必要があります。 やり方としてはいくつもありますが、おそらくBで取得した認証情報などをもう一度Aに引き継ぐ必要があると思いますので、BでセッションのCookieを食わせてAでチェックするとか、隠しフォームにAで使う値をセットしてJavaScriptでPOSTするなどのやりかたが必要になりますね。 (このあたりは実装によって変わるので、ちゃんとアドバイスできませんが) いずれにしても、単純に内部でBからAを呼び出しただけではブラウザは感知できないので、再度ブラウザからAそのものを呼び出さなければならない、ということです。 ご参考になれば。

crescentmonkey
質問者

お礼

ものすごく分かり易い説明に感激です。 ありがとうございます。 宜しければ更にご教示いただけませんか。 認証情報をAに引き継ぐ必要は無いので一番簡単な方法でお願いします。 今回の仕組みは社内use onlyで、会社としてオープン系初tryなので、シンプルイズベスト!です。 かくいう私もperl歴9日目です(^^;) 宜しくお願いします。

関連するQ&A

  • htmlでCGIを作動させたい

    PC用とモバイル用のサイトを作成しています。 http://www.abc.com/ にアクセスすれば自動で振り分けするよう index.cgiというCGIスクリプトを作成しました。 それをindex.html内に組み込んで自動でCGIを呼び出すことは可能でしょうか? 何故わざわざindex.htmlをつくるかというと、METAタグで検索エンジンに引っかかるようにする為です。 <!--#exec cmd="index.cgi"--> を入れてみましたが、振り分け先リンクが表示されるだけで自動では飛んでくれませんでした。 以下、index.htmlのソースです。 <html> <head> <title>ああああ</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta name="description" content="ああああ"> </head> <!--#exec cmd="index.cgi"--> </html> 拙い文章&初歩的な質問で申し訳御座いません。 何卒よろしく御願い致します。

    • ベストアンサー
    • CGI
  • 「 <!--#exec cgi="***.cgi" --> 」が表示されません

    「main.cgi」というファイルを作り、単純にHTMLを表示するだけのCGIファイルを作成しました。 こんな感じ ------------main.cgi------------ #!/usr/local/bin/perl print "Content-type:text/html\n\n"; print <<EOM; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <title></title> </head> <body> <略> </body> </html> EOM __END__ -------------------------------- それで、ほかのHTMLファイルに <!--#exec cgi="main.cgi" --> と入力してそのページを見てみると、 [an error occurred while processing this directive] 上の文章が表示されていました。 どうすれば「main.cgi」の内容を表示することができるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • cgiからcgiを呼び出す方法

    perlのcgi製作を始めて7日目の素人で恐縮ですが、教えてください。 タイトルのキーワードで検索し、いろいろ試しておりますがうまく動作しません。 ■試した例 exec("./cgi A.cgi") <!--#exec cgi="./cgi A.cgi"--> もともと単体で動作していたcgi Aに対して新たにcgi Bを作成し、 cgi Bからcgi Aを呼び出したいのですが、うまくいきません。  cgi A:アンケート回答フォームのようなもの  cgi B:認証フォーム(コードを入力してDB内のデータと一致したらcgi Aを呼び出したい) 自分のPCにApacheをインストールし、ローカルで実行しております。 cgi Bはcgi Aを呼び出す部分をコメントアウトすれば動作します。 どなたか良きアドバイスをよろしくお願いします。

    • ベストアンサー
    • CGI
  • mail送信CGIの返信後のページの文字化け

     フォームからメールを送信するCGIで 送信したあとの、お知らせページが文字化けしてしまいます。どう書いたらいいでしょうか?教えてください。 こんな感じのソースです。。 $header = <<END_OF_DATA; <html> <head> <meta http-equiv="Content-type" content="text/html; charset=Shift_JIS"> <title>メール送信結果</title> </head> <body> <h1>メール送信結果</h1> <hr> <p>御意見、御予約ありがとうございました。</p> <hr> END_OF_DATA  「御意見、御予約ありがとうございました。」というところの、ご予約が文字化けしてしまいます。どのように書いたらいいでしょうか?  ちなみに私はCGI初心者で、これは指示通りに設定しただけなので、分かりやすく教えていただけると嬉しいです。 お願いします<m(__)m>

    • ベストアンサー
    • CGI
  • HTMLからCGIの呼び出しができません。

    既に作ってあるHTMLファイルをコピーして、CGIファイルの名前を変えて送信ボタンをクリックしました。CGIファイルはTITLEだけの記述にしましたが、TITLEは表示されず、http://~のようにアドレスが表示されます。HTMLファイルの方は、<form action="./A.cgi" method="post">のように修正し、CGIファイルの方には、以下のように記述してあります。何が原因でTITLEが表示されないのでしょうか? #!/usr/local/bin/perl use CGI qw(:standard); print<<END_OF_HTM; Content-type:text/html <HTML> <HEAD> <TITLE>XXXXXX</TITLE> </HEAD> </HTML> END_OF_HTM

    • ベストアンサー
    • Perl
  • フォームから入力した漢字が文字化けに

    アンケートを作成しました. 入力フォームに漢字(名前など)を入力して送信すると内容がメールで受け取れます.入力フォームは確認画面が表示できるようにしてありその後,送信でメールを受け取ります.確認画面表示は問題なく2バイト文字は表示されています.そのhtmlファイルの記述に下記設定をしています. <META HTTP-EQUIV='Content-Type' CONTENT='text/html;CHARSET=Shift_JIS'> CHARSET=Shift_JISの部分の指定をいろいろ替えました変化ありません. なにかこのようなことで知ってる方教えてください. また文字コードの制御,フォームとCGIのデータのやりとりなどがわかるサイトや書籍を知ってましたら併せて教えてくださるとありがたいです. よろしくお願いします.

    • 締切済み
    • CGI
  • CGIでCGIを呼び出す方法

    いつもお世話になっています。 今掲示板のCGI(a.cgi)上に広告をランダムで表示するCGI(b.cgi)を記述しているのですがどうにも正しく表示されず困ってます… 他のCGIを呼び出すにはどのように記述すればいいのでしょうか? (htmlでいうとSSIで呼び出すように…)

    • ベストアンサー
    • CGI
  • CGIで作ったHTMLの文字化けについて

    CGIのヘッダを "Content-type: text/html\n\n" として、HTMLをブラウザに出力するcgiを作っているのですが、 「表示」という文字が「侮ヲ」と文字化けしてしまいます。 HTMLの<head></head>内には print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=shift-jis\">"; と記述して日本語を指定しています。 文字化けの原因がまったくわかりません。 心当たりありませんでしょうか?

    • ベストアンサー
    • Perl
  • CGIの呼び出し方法について

    CGIの設定方法について質問があります。 今まで正常に動いていたhtml書き出しのCGIファイル(A.cgi)をコピーしてB.cgiを作りました。 A.cgiに書かれているメールの送信先アドレス$mailtoを変更するとその変更が反映されるのですが、 B.cgiについて同様のことをしても変更が反映されず、変更前のアドレスにメールが送られてきます。 cgiの呼び出し元であるC.htmlにはB.cgiを呼び出すよう記述されており、 書き出されたhtmlはB.cgiとなっています。 <form action="../cgi-local/B.cgi" method="post" name=""> ですが、A.cgiを読みに行っているためA.cgiに書かれているメールの送信先アドレスに送信されています。

    • ベストアンサー
    • HTML
  • CGIにJAVAの記述をしたい

    CGIプログラムの中にJAVAの記述をしたいのですが うまくいきません。 ヒアドキュメントでくくってみましたが 500エラーで表示されませんでした。 どう記述すれば動いてくれるんでしょうか? print "Content-type: text/html\n\n"; print "<html><head>\n"; print "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=Shift_JIS\">\n"; print "<link rel=\"stylesheet\" type=\"text/css\" href=\"$loaddir/style.css\">\n"; print "<title>$title</title>\n"; ここに下記のJAVA文を入れたいです。 print "</head>\n"; 記入したいJAVA <SCRIPT language="JavaScript"> <!-- document.write('<img src="momo/123.cgi?' + 'javaref=' + document.referrer + '" width=1 height=1>'); // --> </SCRIPT>

    • 締切済み
    • CGI

専門家に質問してみよう