- ベストアンサー
ログイン後・・・
こんにちは。サイトを作っているperl初心者です。 TOPページからログインして、メイン画面を表示させたいのですが、つまづいてます。 使用している言語はperl5、データベースはmysql4です。 今「TOPページのcgiのログインフォームからデータを取り、mysqlに接続してデータベースのデータ(id、パスワード)を検索し、 一致するデータがあれば仮にテーブルにして表示させる」ところまではできています。 このテーブルを表示せずに、メイン画面を表示させるためにはどうすればよいのでしょうか? くだらない質問でしょうが、よろしければ回答を。 よろしくお願いします。
- みんなの回答 (14)
- 専門家の回答
質問者が選んだベストアンサー
> すみません!ちょっと伺いたいんですけど。 > phpのheaderっていう関数と同じの機能のものって、perlにもありますか? ないとは思いますが、単にANo.12で挙げたとおり、出力の順番を考慮したうえで printすればいいと思うのですが、それだとまずいのですか? Perlでも何でもそうですが、実際のHTML送出前にヘッダをprintしてあげれば それで解決すると思うのですが…。 今回の件では、認証の結果如何で出力しなければならないHTTPヘッダがあるのにも関わらず、 認証判断前にHTTPヘッダもHTMLも出力してしまっているのが問題なわけですから、 判断後に状況に合わせた出力方法に変更するだけで対応可能です。 Googleで「CGI HTTPヘッダ」で検索した中で、そこそこ解りやすそうだったサイトを提示しておきます。
その他の回答 (13)
- taka451213
- ベストアンサー率47% (436/922)
いったい何がやりたいのか・・・??? PHPがわかるなら、PHPで作ればいいものを・・・。 >> phpのheaderっていう関数と同じの機能のものって、 >>perlにもありますか? ありません。 単純にレスポンスヘッダ(と空行)を出力してから、実際のHTMLを出せばいいだけなのに・・・。 CGIで出力するべきレスポンスヘッダは、 print "Content-Type: text/html", "\n\n"; たったこれだけ。 足りない分はサーバーが補填して出力してくれる(別に自力で出しても構わないが・・・)。 だんだん本題からズレてしまっているようだ・・・。
お礼
サンプルソースが他になかったもので、このサンプルソースが使っている perl言語を学ぼうとしているだけです。 ちなみにphpはもっとわかりません。 回答ありがとうございます。
- breezegale
- ベストアンサー率50% (7/14)
Perlやmysqlの認証というより、CGIからHTMLを出力する時の流儀について、もう少し理解されないとちょっと難しいかもしれませんね…。 > print <<header; > Content-Type:text/html > > <html> > <head> > <meta http-equiv="Content-Type" content="text/html";charset=Shift_JIS"> > <title>★○○○★</title> > </head> > <body bgdolor="#ffffff" text="#000000"> > header ヒアドキュメントで共通するHTML部分まで既に出力しちゃっているため、後からLocationヘッダを出力しても、 単なるHTML内の内容として出力されてしまっているために「表示されるだけ」になっています。 上記では、ちょうと「Content-type: text/html」の部分がHTTPヘッダになってますから、 ここに追加する形(じゃないな、リダイレクトだけならContent-typeは要らないか)でLocationが 入らないと意味がないです。 従って、認証の可否分岐前にここまで出力しちゃうのがダメだと思います。 以下、構造だけ。(概念だけとらえて、実際のコーディングはやってみてください) if (データが与えられてない) { # 上記の出力+エラーメッセージ } elsif (認証が通らない) { # 上記の出力+エラーメッセージ } else { # 通ったのでリダイレクト print "Location: index.cgi\n\n"; } …という感じでしょうか。要は成功するのかしないのか判別できるまではHTTPヘッダを出力しないことがポイントです。 CGIを使用する際にHTTPヘッダをどうやって出力するのか、という部分について勉強してみてください。 これはCGIにPerl以外の言語を使っていても同じ知識ですので。 (恐らくHTTPヘッダとHTMLの出力についての切り分けができていない気がします)
お礼
回答ありがとうございます。 そうですね、やっぱりまだ理解してない部分が多いのだと思います。 ネットなどでhttpについてもう少し調べてみます。
補足
すみません!ちょっと伺いたいんですけど。 phpのheaderっていう関数と同じの機能のものって、perlにもありますか?
- taka451213
- ベストアンサー率47% (436/922)
う~ん・・・。 こういう言い方はなんだが、 もう少しPerlを理解してからでないと難しそう・・・。 index.cgi の中身は、何が書いてあるの???
お礼
いやぁ実は卒論でオークションサイト作っていて、しかも取り組み を始めたのがとても遅かったので、もう勉強する時間ないんですよね~(^^;) それで、ここで質問したってわけなんですけど、やっぱ理解してない部分が 多すぎてなかなか難しいですね。。 index.cgiには出品一覧を作成してするためのcgiプログラムが、480行にまたがって ずらずらと記述されております。 回答ありがとうございます。
- breezegale
- ベストアンサー率50% (7/14)
> 一応このように記述したのですが・・・ > →print "Location:<A href=\"./index.cgi>\n\n"; > このまま文が表示されるだけなんです。 HTMLとして出力するのではなく、HTTPヘッダとして出力する必要があります。 上記のprintをする前に既にヘッダ部分の出力をしていませんか? 恐らくContent-type等のヘッダ情報を出力するルーチンが認証プログラムにあるはずですので、そこの改造が必要です。 また、あくまでHTTPヘッダですから、HTMLでの記述ではなく、 print "Location: /index.cgi\n\n"; といった表現になります。 なお、HTTPヘッダの出力セクションにおいて空行を用意してしまう(print "ヘッダ\n\n";と\nで2回改行する等)と、 その時点でヘッダは終了と認識されます。ご注意ください。 mysqlの認証というより、これはCGIでの出力やHTTPの仕組み&流儀にかかってくる部分ですので、 まずはCGIの作り方について詳しく調べられるとよいと思います。がんばってください。
補足
回答ありがとうございます。 実はheader文省略としたところに以下のような記述がしてあります。 print <<header; Content-Type:text/html <html> <head> <meta http-equiv="Content-Type" content="text/html";charset=Shift_JIS"> <title>★○○○★</title> </head> <body bgdolor="#ffffff" text="#000000"> header この部分がおかしいのでしょうか?
- taka451213
- ベストアンサー率47% (436/922)
index.cgi に飛ばしたいのなら、 print "Location: /index.cgi"."\n\n"; でしょ???
お礼
回答ありがとうございます。 指摘されたように書き直してみましたが、できないみたいです(T_T) うぅ・・・
- breezegale
- ベストアンサー率50% (7/14)
なんか少し判った気がします。 認証を通過した後、別のプログラムを呼びたいということなんですね。 であれば、直接的にプログラムを呼ぶのではなく、taka451213さんの言われるようにLocationヘッダでリダイレクトをすればいいでしょう。 あるいは究極的には認証構造自体をメインのプログラムに組み込んでしまい、2段階でやらずに1本のプログラムでできるようにしてしまうか、ですね。 CGIの場合、外部のプログラムに制御自体を丸ごと渡すというのは色々やばそうな気がしますので、統合するか、分ける必要があるならリダイレクトして別のファイルを読み直させる方法しかないでしょう。 (LocationにはCGIを指定しても大丈夫です) ただし、リダイレクトをした場合はANo.4でも挙げましたが、飛び先のURLが判ってしまえば認証は完全に不要になってしまいます。 もしそれでも認証したかどうかを確認するならば、飛び先側のプログラムで認証済みか否かを知るための仕組が別途必要です。 それはCookieなのかPOSTやGETによるものなのかはサイトの構築方法次第となるので、ここでは言いようがありませんが…。
補足
回答ありがとうございます。そうなんです、別プログラムを呼びたいんです。 taka451213さんのおっしゃったようにprint文でやってみましたが、 文がまちがっているのかできませんでした(>_<;) 一応このように記述したのですが・・・ →print "Location:<A href=\"./index.cgi>\n\n"; このまま文が表示されるだけなんです。 初心者で何をいじっていいのやら全くわかってなくてすみません。 何が間違ってますかねぇ??
- taka451213
- ベストアンサー率47% (436/922)
だったら、すでにあるメイン画面の print って書いてあるあたりをゴッソリコピーして、 print "Location: xxxx.html\n\n"; の部分に書けばいいのでは?
お礼
回答ありがとうございます。 なんかmainページには複雑なプログラムが書かれていて、 ご指摘のようにはいかないようです。 すみません。。。
- taka451213
- ベストアンサー率47% (436/922)
>>※元々テーブルで検索結果を表示していました。 >>この部分が知りたいんですが・・・ ここにメイン画面を書けばいいのでは??? タグを書くのが面倒なら、メイン画面のHTMLを作っておいて、 print "Location: xxxx.html\n\n"; とかなんとか、書いてしまえばいい・・・。 (^^ゞ
お礼
すみません、一言お礼が言いたくて古い回答のお礼フォームに 書いてます。 おかげさまで解決いたしました。ご迷惑おかけしました。 認証時のエラーメッセージが原因だったので、サブルーチンで飛ばしました。 助かりました。ありがとうございました。
補足
これサンプルソース使っていて、main画面はすでにあるのですが、それもcgiで書かれているんですよ~(^^;) print "Location: xxxx.html\n\n";のhtmlの部分をcgiに直してもできますかね?
- taka451213
- ベストアンサー率47% (436/922)
MySQL接続ページって何??? それもひとつのHTMLですか? それは接続と認証のルーチンを持っているわけではなく、単にDBの取得結果を表示しているだけのHTMLですよね? なので、それがいらないです・・・。 実際にDBにconnectして、TOP画面で入力されたパラメーターでDB検索して、IDとパスワードが存在するかどうかをチェックしているのはCGIでしょ? 今は取得するまでがプログラムで、認証結果いかんにかかわらず結果表示画面のHTMLに行ってるんですよね? そこに、あった時となかった時の振り分けを書いて、それぞれ違うページ(HTML)に行くように変更すればいいのでは? という事が言いたかったのですが・・・。 (^^ゞ
補足
どうも私は言葉で説明する事がうまくないようです。 すみません(^^;)以下にMysql接続ページなるものの内容を載せます。 間違いがあればまたご指摘よろしくお願いします。 #!/usr/local/bin/perl use CGI qw(:standard); use DBI; $dbn = "DBI:mysql:sample1:localhost"; $user = "*****"; $pw = "*****"; $i_id = param("s_id"); #パラメータ取得 $i_pw = param("s_pw"); # 〃 print ※header情報省略 $dbh = DBI->connect($dbn,$user,$pw); #データベースハンドル生成 $dbh->do("SET NAMES sjis"); $sth = $dbh->prepare("select * from list where id =" .$i_id); #ステートメントハンドルの生成 if($sth->execute() == 0) { print "<font color=blue>idがまちがっていませんか?<br>データがありません!</font>"; #実行後、結果が0ならエラー表示 } else { @row = $sth->fetchrow_array(); #そうじゃなければ、データを取り出して格納 if ($row[1] ne $i_pw) { print "<font color=red>pwがまちがっていませんか?<br>データがありません!</font>"; #パスワードが合致しなければエラー表示 } else { ※元々テーブルで検索結果を表示していました。この部分が知りたいんですが・・・ } } $sth->finish(); $dbh->disconnect(); print ※footer情報省略 exit;
- breezegale
- ベストアンサー率50% (7/14)
他の方も指摘していますが、テーブルを表示するルーチンではなく、そのまま認証OKになったら メインのコンテンツを出力するように仕向ければいいと思います。 ANo.1の補足質問で書かれていることから、mysql認証プログラムが通った後、 メインコンテンツ表示プログラムに制御を移したい、ということだと思うのですが 合っていますでしょうか。 とすると、mysql認証プログラムとメインコンテンツ表示プログラムは別のものであるわけですから、 いきなりmysql認証プログラム上で別のファイルのサブルーチンを呼んでも呼べないと思います。 もしやるのであれば、mysql認証プログラムで認証OKになった後、 <META http-equiv="Refresh" content="0; URL=*メインページURL*">などと出力すれば解決できる気がします。 が、これだとメインページのURLが判ってしまうとmysql認証を通らなくてもいけるようになってしまいますから、 mysql認証OKの段階でCookieを食わせるとかで認証完了済みかどうかのステータスを保持させ、 以後のコンテンツでこのCookieを確認して未認証状態なら強制的に認証をさせ構造を作る必要が出てくるものと思います。 どのようなサイト構成をお考えかが判らないので何とも言えないのですが、 単にメインページの表示だけ認証が必要なのであれば、mysql認証プログラム内にメインコンテンツを 出力するようなルーチンを書いてしまえば楽になるように思います。 やられようとしていることに合致しているかどうかちょっと自信ないのですが…参考になれば幸いです。
お礼
回答ありがとうございます。 >mysql認証プログラム内にメインコンテンツを >出力するようなルーチンを書いてしまえば楽になるように思いま>す。 そうなんですよ、それがやりたいんですができないんですよね~これが(^^;) Cookieの使い方も良くわからないので調べてみます。ありがとうございます。
- 1
- 2
お礼
回答ありがとうございます。 なんとかできました!(下手なりにですが・・・) locationを記述してもできなかったのでなぜだろうとなやんでいましたが、 どうやらエラーメッセージのところでひっかかっていたようです。 そりゃそうですよね、上部のヘッダ情報は消してるのに<font>って書いて しまっているのだからf(..) ふぅ~本当に助かりました。ありがとうございました。