「URL パラメータを取得する」では、 JavaScript を使用して、 js-getparam.html?name=Tom&favorite=vegetables のように、URL の末尾にパラメータを付けて html を開き、 それを JavaScript で解析して処理を変える、という処理を実装できるようになりました。 いわゆる GET 方式で渡しています。
今度は URL にパラメータが見えない POST 方式でパラメータを渡したいと思います。
こうすると、パラメータを入力したあとの URL をブックマークできなくなりますから、 非常に簡易的なパスワード保護されたコンテンツを作成できるのではないかと考えています。
なお、この先にある perl の cgi コードをローカルな環境で動作させるには、
Windows の場合、「Web サーバーソフト」と呼ばれている
IIS 10 express をセットアップして localhost を使う
JavaScript で HTTP リクエスト XMLHttpRequest を実行したり、perl cgi を使うコードをローカルでテストするには、
Windows の場合、IIS 10 express などを事前に用意しておかなくてはなりません。
なお、本サイトの
ご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。
投稿 September 27, 2022
基本は、form にテキスト入力欄などを設けて
ここに用意した form を置いておきます。
なお、post メソッドのテストのために用意したものですから、ここで入力されたデータがサーバー側に保管されることはありません。 安心してお試しいただけますが、それでもデータはネットワークを通りますので、差し障りのない文字のみにしてください。
ここでは form の中身について、簡単に書いておきます。
<form action="http://localhost/web/post-param.cgi" method="post">
ここにパーツを書き込みます。
</form>
ここにある action の値については、 のちほど検証します。
まず最初に「Enter the magic word」と書いたテキスト入力欄です。 ここに入力されたテキストが正しいかどうか、判断を行うような cgi にしていますので、パスワードのようなイメージです。
<label for="text_magicword">Enter the magic word: </label> <input type="text" name="text_magicword" id="text_magicword" value="" size="20">
最初の行の label は、関連するテキストを配置するものです。 for に対応するコントロールの id を記入すると、そのテキストのクリックでフォーカスが対応するコントロールに移るようです。 つまり for がないか、または id と異なる値が記入されている場合、テキスト部をクリックしても何も起きません。 正しく指定されていれば、テキスト部のクリックで、入力欄をクリックしたのと同じ効果を得られるようです。
2 行目の input は type="text" 指定ですので、
name で指定した文字列が、cgi に渡されるキー名になります。 例えば "california" と入力した場合、cgi に送信されるデータは、次のようになります(パラメータ単独の場合)。
text_magicword=california
次に用意したのは、ドロップダウン リストです。 スマホでは選択肢からの 1 つ選択になると思います。
<label for="option_destination">カリフォルニアで行きたい場所は?</label> <select name="option_destination" id="option_destination"> <option value="disney">ディズニーランド</option> <option value="seaworld">シーワールド・サンディエゴ</option> <option value="silliconvalley">シリコンバレー</option> <option value="wharf">フィッシャーマンズワーフ</option> <option value="napa">ナパバレー</option> <option value="other">その他</option> </select>
テストなのでこんなにたくさんの選択肢を用意する意味はありませんが、せっかくなので form の備忘録にもしたいです。
先ほどと同様、label はコントロールに対応する説明書きです。
続く select が、ドロップダウン リストの定義です。 </select> までの間に、選択肢の数だけ option を配置します。 name で指定した文字列が、cgi に渡されるキー名になります。
それぞれの option には、 それが選択されたときに送信される文字列を定義した value と、 画面に表示される文字列を指定します。
例えば「ディズニーランド」が選択された場合、cgi に送信されるデータは、次のようになります(テキスト入力欄もある場合)。
text_magicword=california&option_destination=disney
パラメータの区切りは & となります。
次に用意した選択方法は、Windows ではラジオボタンとか呼んでいますが、 一般にはオプションボタンと呼ぶのでしょうか?
<fieldset> <legend>希望の座席クラスは?</legend> <input type="radio" name="radio_seat" value="first" /> ファースト <input type="radio" name="radio_seat" value="business" /> ビジネス <input type="radio" name="radio_seat" value="premium" /> プレミアム・エコノミー <input type="radio" name="radio_seat" value="economy" checked /> エコノミー </fieldset>
あまり試していないので記述が正確ではないかもしれませんが、 まず fieldset で囲んだ内側は、枠の中に入るようです。 Windows でいう group に該当するものと思われます。 これは「オプションボタンだから必要」というものではないようで、見え方が変わるだけで、なくても問題ありません。
legend に説明書きを入れるようですが、その意味はまだ理解していません。
それぞれの項目は input の type="radio" で指定します。 "radio" と書かれていますから、プログラム的には「ラジオボタン」と呼んで良さそうです。
同じ name 文字列を持つものがグループとして扱われるようです。 ですので離れたところに配置されたとしても、同じラジオボタン・グループになるようです。 「グループ開始」や「グループ終わり」のマークは必要ありません。
value に書かれた文字列が cgi プログラムに渡されることになります。
text_magicword=california&option_destination=disney&radio_seat=economy
checked と書かれた項目が、初期状態で選択されます。
入力項目の最後は、複数行のテキスト入力欄です。 コメントとか連絡事項とかを記入してもらうような感じですね。
<label for="textarea_text">特別なリクエストなどがありましたら記入してください。</label><br/> <textarea name="textarea_text" id="textarea_text" rows="4" cols="40"></textarea>
label は説明テキストで、for で対応するコントロールの id を指定しておきます。
続く textarea が、複数行のテキスト入力欄となります。 name でキー名を指定しています。
入力されたテキストはそのまま(エンコードされて)name の値として送信されます。 改行コードは、%0D%0A として渡されます。 意味としては 16 進数で 0D と 0A で、CR/LF と呼ばれる改行コードになっているように見えます。
最後に 送信ボタンと リセットボタンです。
<input type="submit" name="submit" value="送信"> <input type="reset" value="リセット">
input に type="submit" と書くと、送信ボタンになるようです。 ボタン表面に書かれる文字は value で指定されるようですが、 同時に name に書かれたキー名とともに渡されてしまいます。 どういう風に使うと便利なのでしょうか? 試しに name をまるごと削除してみると、 問題なく動作する上に「送信」がパラメータに含まれなくなりましたので、それでいいのかもしれません。
type="reset" を用意しておけば、全てのコントロールを初期状態に戻せるようです。
最後の最後に一番最初の form の action の値に戻ります。
<form action="http://localhost/web/post-param.cgi" method="post">
本来はここにはサーバーにある cgi プログラムへのパスを指定します。
ここにあるように http://localhost/ で始まる指定にすると、 ローカルで、IIS が設定した、cgi プログラムを実行できるパスにある cgi プログラムを実行させることができます。
この書き方の場合、 「IIS 10 express をセットアップして localhost を使う」 のようにローカルにセットアップした perl で動作できる、 C:\inetpub\wwwroot にある web サブフォルダを指す形になります。 cgi プログラムはこのように決まった位置に配置する必要があります。 cgi を呼び出す html は、どこにあっても構いません。
サーバーにアップロードするまでは、この形でテスト可能です。
次は、データ受領側 cgi を用意します。
投稿 September 27, 2022
まず改めて、少なくとも Windows では、そのままの状態では cgi をローカルでテストできません。 「IIS 10 express をセットアップして localhost を使う」のように、 実行環境をセットしておくことで、ローカルで cgi を動作させることができます。 実際のサーバーで cgi をデバッグするのは危険ですし、手順としても相当面倒になりますから、 ローカルでテストできる環境を作るほうが良いと思います。
ここでは perl で記述しようとしていますので、post-param.cgi の最初の行に、perl のパスを記述します。 ファイル名は form の action に書いたものと一致する必要がありますが、 どのような名前にしても構いません。
ファイルを置く場所は、IIS で設定しtた、C:\inetpub\wwwroot\ あるいは指定したパスです。 ここではサブフォルダ web を置いて、その中に post-param.cgi を置くことにしています。
#!/usr/local/bin/perl
基本的なところはここでは書きませんが、cgi プログラムは html コードを返す(出力する)必要がありますので、 まずは以降で共通に使うヘッダ部を出力します。
&putHeader;
putHeader という名前の関数を呼び出すコードです。 このように書くようです。
関数はこのように定義していますが、プログラムのコード終了を示す exit; 以降に記述します。
sub putHeader { print "Content-type: text/html\n\n"; print << "eof_header"; <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <title>POST PARAM CGI ページ - StraightApps.com</title> </head> <body> eof_header
まず、応答は html であるという出力を行います。 どうやらこれがないと、文字がそのまま表示されてしまうようです。
その後すぐにある print << は、続くラベル指定 eof_header に当たるまで、 連続して html 出力を行うための書き方です。 そのあと必ず 1 行あけて、出力する html コードを記述します。
html 出力の終了は、ラベルを必ず行の先頭から記述します。 ラベルをタブでインデントしたり、うっかりセミコロンを付けてしまうと正しく動作しません。
今は最小限のコードしか書いていませんが、本当はちゃんとしっかり書くべきです。
メインの流れ、&putHeader; 続きに戻ります。
このプログラムは POST メソッドでのパラメータ渡しを前提としていますので、 安全のため、POST 以外のケースを除外します。 例えば cgi の URL を直接入力、あるいはブックマークしてのアクセスでは、POST でパラメータは来ませんので、ここではじかれます。
$method = $ENV{"REQUEST_METHOD"}; if ($method ne "POST"){ print "<p>method が POST ではありませんでした。</p>"; &putFooter; exit; }
最初の行、$ENV{"REQUEST_METHOD"} で、環境変数
これが
POST メソッドでなければ、print 文で html テキストを出力し、 続く &putFooter で共通のフッタを出力します。
putFooter 関数は、putHeader 関数のあとに記述しますが、順序は関係ないでしょう。
sub putFooter { print << "eof_footer"; <a href="#" onclick="javascript:window.history.back(-1);return false;">Back</a> </body> </html> eof_footer }
putHeader 関数に対応するように、html を完了させるコードを putFooter 関数で出力しています。 ついでに Back のリンクを追加し、呼び出し元のページに簡単に戻れるようにしています。
if に戻ると、そこに exit; がありますので、これで cgi プログラムは終了となります。 ここまでで理解可能な html がちゃんと出力されている必要があります。
パラメータの取得や処理は多少面倒ですから、今は全体像を見ておきます。
print "<p>method は POST でした。</p>";
とりあえずは、POST でパラメータが渡されたことを明示できるよう、テキストを出力しておきます。
パラメータを解析しない場合は、これでフッターを出力すれば完了です。
&putFooter; exit;
フッタを出力して html を完成されたら、exit; で終了します。
このあとに、putHeader 関数や putFooter 関数を記述します。
投稿 September 27, 2022
いよいよ POST メソッドで渡されたパラメータを解析し、 それによって異なる処理を実行しようと思います。
この初期リリースはここまででいったん休憩し、改めてここに追記していきます。
2022 年 6 月をもって、楽天モバイルの 0 円プランが廃止され、新プランに自動移行されました。 9 月からは実質的に有料になりますから、それまでに別の回線にするか、このまま使うかを決めなくてはいけません。
支払い手段に楽天カードを指定している楽天モバイルですが、カードが更新されたら手動でカード情報を更新する必要があるのでしょうか?
Android の操作に関する記事をまとめた Android 操作トップ もご覧ください。