- ベストアンサー
CGIへの引数の渡し方
直接プログラミングと関係あるかは分かりませんが、 Webなどでよく見る送信ボタンなどの、いわゆる"submit"を押したとき、 CGIが呼び出されることがよくあります。 実は今、あるページから項目を入力して送信ボタンを押すという行為を定期的に繰り返しているのですが、それをプログラムで書きたいと思いました。 そこで質問なのですが、"submit"などからCGIを呼び出したとき、CGIはいったいどうやって入力されたデータなどを読み取っているのでしょうか? CGIについての知識はあまりないのですが、引数として渡されるのでしょうか? (http://aaa.bbb/ccc.cgi?name=100 見たいな感じで) ちょっと調べてみたら上のような感じだと書いてあったので、web上のcgiが呼び出されるhtmlのソースを呼んで、Inputのnameがnameだったので、 ?name=abc としたのですが、何も起こりませんでした・・・ その当たりがよく分からないのでどなたか教えていただけると助かります。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
> POST用に作られたcgiへ引数を渡すときは、 > web上のinputからの入力しかないのでしょうか・・・ > でもブラウザはそれをやっているのですから、プログラムで作れなくはないと思うのですが web上のinputからの入力じゃなくても全然かまいませんし、プログラムでもOKです。たとえば、あるCGIスクリプトが他のページにPOSTするのは良くありますし。 > CGIはいったいどうやって入力されたデータなどを読み取っているのでしょうか? まず「読み取り方」より先に「どのようなデータが送られているのか?」が解れば、CGIはそれを読み取っているだけです。 基本的にHTTPでは、テキストで書かれたヘッダと、必要ならデータを送るだけのことです。 とりあえず、URLの末尾に付いた「?~」、つまりブラウザの「アドレス」欄で人間が見ることができる部分のことは、ちょっと忘れてください。 実際にブラウザ(またはプログラム)が、どのようなデータを(裏で)送っているか、以下説明します。 たとえば「name=abc」というデータを「test.cgi」に送りたい場合、以下のような内容を送っています。たったこれだけです…。 GETの場合 ------------------------ GET /test.cgi?name=abc HTTP/1.0 Host: www.okweb.jp ------------------------ POSTの場合 ------------------------ POST /test.cgi HTTP/1.0 Host: www.okweb.jp Content-Length: 8 name=abc ------------------------ ※先頭に「HTTP/1.0」とありますが、このHTTPバージョンによって若干異なります。また上記はあくまでも簡単に書いたもので、実際は他にもいろいろ書く場合があります。 具体的にgenki140さんがやろうとされていることは解りませんが、たとえばperlスクリプトから他のサイトのCGIにPOSTさせたいなら、とても簡単な方法としては、Socketモジュールを使って、SOCKETを開いた後、あたかもファイルに書き出すように、 print SOCKET "POST $path HTTP/1.0\r\n"; print SOCKET "Host: $host:$port\r\n"; print SOCKET "Content-Length: $len_arg\r\n"; print SOCKET "\r\n"; print SOCKET "$send_arg\r\n"; … という具合にprintしていくだけです。
その他の回答 (4)
- taseki
- ベストアンサー率66% (155/233)
> では、上のように書いた場合、cgiの結果が返すhtmlなどを読むこともできますか? もちろんできます。というか、それができなければ意味がないですよね(笑)。投げっぱなしというか。 よくあるダウンローダーや巡回ソフトがそうです。なにより、ブラウザがやっているのも同じです。 GETかPOSTかの違いはあるかもしれませんが、リクエストのしかたが違うだけで、接続→リクエストを送る→レスポンスを受け取る→表示または保存など、という流れです。 > あと、できればC言語で書きたいのですが、C言語のWinSock32でもできるんでしょうか・・・ 「C言語の」というよりウィンドウズのソケットですね。たいていソケットはOSが提供するものなので、perlでもCでもVBでもWSHでも、もっと言えば、どのOSでも基本的にソケットの仕組みは同じなので、要領は同じです。サンプルのように、ソケットの前準備(開いて接続など)、データ送信(この場合POST)、レスポンスを読み取る、…その他、という流れです。 ソケットを開いて接続、などの処理はお決まりの流れで良いとして、今回のポイントになるのはPOSTデータの作り方になると思います。 これはHTTPの仕様(RFC)で定められていて、たとえばサンプルを見れば解るとおり改行は「\r\n」であることや、ヘッダとボディの間には必ず空行を入れることや、ボディ、つまりPOSTしたいデータの中身はURLエンコードという変換(スペースを+記号に、など)をすること、などのルールがあります。 本来は仕様書を見るのが一番ですが、ご存知かもしれませんがRFCを読むのは結構キツイですよね…。 なので、「HTTPプロトコル」などで検索して必要十分な情報をとりあえず得られたら、作成されたプログラムからまずはGETをためしてみて、うまくいけばプログラム自体に問題はないですから、それからPOSTをやってみるといいと思います。 必要十分な情報…、というのは具体的には難しいですが、今見つけたのは↓とか。 http://www.rfs.jp/sitebuilder/perl/03/03.html perlのページですが、HTTP プロトコルの基礎あたりと具体例が載っています。 とにかくGETを試してみることで、相手サーバーに(極端に大量アクセスしなければ)特に大きな迷惑がかかることはありませんので、Yahooなどを相手にGETしてみましょう。それからPOSTの実験でも、Web検索が使えると思います(POSTも受け付ける※エンジンによる)。
お礼
具体的で分かりやすい回答、ありがとうございました! とりあえずはGetから、一生懸命やってみます! それでも分からなかったらまた質問するかもしれませんが、とにかく挑戦してみます。 本当にいろいろありがとうございました!!
- Sucelggug(@xyz37005)
- ベストアンサー率51% (369/715)
HTMLファイルのINPUTタグ以外の方法でPOST形式のデータを送る方法はないと思います。 少なくとも私は知りません。 以前作ったHTMLとCGIのサンプルを紹介します。 -- form.htm ------------------------------- <html> <body> <form action="../../cgi-bin/kakunin.cgi" method="post"> <table><tr> <td>名前</td> <td><input type="text" name="name" size="30"></td> </tr> <tr> <td>出身地</td> <td> <select name="home"> <option value="大阪府">大阪府</option> <option value="京都府">京都府</option> <option value="兵庫県">兵庫県</option> <option value="和歌山県">和歌山県</option> <option value="奈良県">奈良県</option> </select> </td> </tr> <tr> <td>性別:</td> <td> <input type=radio name="sex" value="MAN" checked>男 <input type=radio name="sex" value="FIMALE">女 </td> </tr> <tr> <td>趣味:</td> <td> <input type=checkbox name="hobby1" value="PC">パソコン <input type=checkbox name="hobby2" value="SP">スポーツ <input type=checkbox name="hobby3" value="RD">読書 </td> </tr> <tr> <td><input type="submit" value="登録"></td> <td><input type="reset" value="クリア"></td> </tr> </table> </form> </body> </html> ------------------------------------------- -- kakunin.cgi ---------------------------- #!C:/Perl/bin/perl #フォーム(POST)の内容を受け取る read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); @pairs=split(/&/,$buffer); foreach $pair (@pairs){ ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C",hex($1))/eg; $form{$name} = $value; } $name = $form{'name'}; $home = $form{'home'}; $sex = $form{'sex'}; $hobby1 = $form{'hobby1'}; $hobby2 = $form{'hobby2'}; $hobby3 = $form{'hobby3'}; print "Content-type: text/html\n"; print "\n"; print "<HTML>\n"; print "<BODY>\n"; print "確認画面<br>\n"; print "<table border><tr> \n"; print "<td>名前</td><td>$name</td> \n"; print "</tr><tr> \n"; print "<td>出身地</td> \n"; print "<td>$home</td> \n"; print "</tr><tr> \n"; print "<td>性別</td> \n"; print "<td> \n"; if( $sex eq "MAN" ){ print "<input type=radio name='sex' value='MAN' checked>男 \n"; print "<input type=radio name='sex' value='FIMALE'>女 \n"; }else{ print "<input type=radio name='sex' value='MAN'>男 \n"; print "<input type=radio name='sex' value='FIMALE' checked>女 \n"; } print "</td> \n"; print "</tr><tr> \n"; print "<td>趣味</td> \n"; print "<td> \n"; if( $hobby1 eq "PC" ){ print "<input type=checkbox name='hobby1' value='PC' checked>パソ\コン \n"; }else{ print "<input type=checkbox name='hobby1' value='PC'>パソ\コン \n"; } if( $hobby2 eq "SP" ){ print "<input type=checkbox name='hobby2' value='SP' checked>スポーツ \n"; }else{ print "<input type=checkbox name='hobby2' value='SP'>スポーツ \n"; } if( $hobby3 eq "RD" ){ print "<input type=checkbox name='hobby3' value='RD' checked>読書 \n"; }else{ print "<input type=checkbox name='hobby3' value='RD'>読書 \n"; } print "</td> \n"; print "</tr></table> \n"; print "</BODY>\n"; print "</HTML>\n"; exit; -------------------------------------------
こちらをごらんください。
- Sucelggug(@xyz37005)
- ベストアンサー率51% (369/715)
CGIへのデータの受け渡し方にはPOSTという方式とGETという方式があります。 >CGIについての知識はあまりないのですが、引数として渡されるのでしょうか? >(http://aaa.bbb/ccc.cgi?name=100 見たいな感じで) →これはGET >web上のcgiが呼び出されるhtmlのソースを呼んで、 >Inputのnameがnameだったので、 →これはPOST その他詳しいことは項目が多すぎてここでは説明できないので 参照URLを見てください。
補足
アドバイスありがとうございます。 参考URLなどを読み、大体は分かりました。 では、POST用に作られたcgiへ引数を渡すときは、 web上のinputからの入力しかないのでしょうか・・・ でもブラウザはそれをやっているのですから、プログラムで作れなくはないと思うのですが、やっぱりやり方がわかりません。 もう少し情報があったらお願いしますm(_ _)m
補足
とても分かりやすい回答どうもありがとうございます。 なるほど、そうやって直接ヘッダを送るだけでPOSTすることができるんですね。 perlはあんまりよく分かりませんが、なんとなく分かりました。 では、上のように書いた場合、cgiの結果が返すhtmlなどを読むこともできますか? あと、できればC言語で書きたいのですが、C言語のWinSock32でもできるんでしょうか・・・ 具体的に何がやりたいかというと、 あるページで項目を入力して送信ボタンをおし、 結果返ってくるhtmlの内容を読み取って保存する。 この作業を定期的に行いたいんです。 しつこくてすみません・・・どうかお願いします。