プログラミング Tips

ITエンジニアの雑記ブログ。
IT関連ニュースの考察や、プログラミングに関するTipsの備忘録として…
育児や日常の雑記帳としても、記事を投稿していきます。

プログラミングと日常生活に関する情報を発信しています。

カテゴリ:WEB > HTML5

input要素は、type属性の指定によって表示形態がことなる。

例えば、フォームの中で'<input type="text">'と記述すれば、テキスト欄が表示される。
また'type="submit"'と記述すれば、送信ボタンになる。

type属性にはいくつかの指定要素が存在するが、その中に"hidden"がある。
"hidden"を指定されたinput要素は、ブラウザの画面上に何も表示されない。

hiddenを指定しても改行をともなわず、タグ位置にスペースが入ることもない。
HTMLドキュメントを描画する際には完全に無視された存在になっている。

描画された画面からはわからないが、リストのフォームから送信すると、きちんとaction属性で指定されたページに、hidden要素が指定されたinput要素も送信される。

書籍や雑誌に掲載されれているサンプルコードにhiddenを入れている例は少ない。
一方、実際にWEBサイトを構築するとhidden要素の使用頻度は想像以上に高い。

hiddenは、閲覧者に意識させることなく裏側でデータをサーバーに送信する

例えば1ページに1問ずつ回答、合計3問のアンケートサイトの場合。
実際にデータを送信するのは、3ページ目の処理になる。

この場合、1ページ目の入力内容を2ページ目、3ページ目でも維持しておけなければならない。
1ページ目でテキストを入力、2ページ目はその結果をhiddenに入れておく、3ページ目に送信するといった処理を行う必要がある。 

このように、直前のページから得た入力値をブラウザの画面に見せることなく、次のページに引き継ぐ手法としてhiddenは有効。
 
ただし、データを引き継ぐためにはJavaScript、またはサーバーサイドの処理が必要。
POSTで送信する場合、JavaScript(GETしか処理できない)が使用できない

尚、POSTで送信するとhiddenで指定された入力値は画面上には表示されないが、HTMLドキュメントのソースを見られてしまうと値がみえてしまう。よって完璧に隠すこそはできない。

よってhidden指定値は、簡易的にログイン状態の保持などに使用できるが、IDやパスワードを格納しておく使い方は危険であることがわかる。

前回の投稿で、「GETとPOSTはどっちが優秀?」って記事を書いたけど、

そもそも"GET"と"POST"は併用はできないのだろうか??

って疑問が浮かんだので調べてみた!
で、答えは「併用できる」だった。

それほど難しい仕組みでもないし、知ってしまえば「そうだよね!」ってことだけど、
意外に最初は!?!?って感じだったので、備忘録のために残す。

フォーム要素の指定は、どちらかひとつ
まずフォーム要素を指定する場合には、

<form method="GET">
のようにGETかPOSのいずれかしか指定できない。
"method=GET,POST"などの書き方は存在せず、エラーになる。

では、「併用できない」ではないか!と思った方!
焦らずに次の行を見てください。

<form method="POST" action="sample.php?str=ABC">
この記述はどうだろうか?

methodに"POST"、メッセージボディに"GET"引数を追加

HTMLでは、

<form method="POST" action="sample.php?str=ABC">
のようなフォーム要素の記述ができるため、action属性に「?」から始まるGET引数を付与することで、GETとPOSTの両方が有効になる。

ただし、あくまでもフォームからの送信にはmethod="POST"が有効で、メッセージボディに含まれる形でGET引数を受け取ることになる。

POSTとGETのハイブリット型データ送信と言える。

HTTPヘッダーの中身を確認するとわかるが、リクエストそのものはフォームが"POST"メソッドで送信していることがわかる。しかし、遷移後の"sample.php"のブラウザURL欄には「http://.../sample.php?str=ABC」になる。
実際、サーバサイド処理において、このハイブリット形式はGET分のデータもPOST分のデータも問題なく処理できる。

また、フォームからの送信データ、特にPOSTで送られたモノについては、PHPなどのサーバサイドしか処理できないが、GET引数に関してはクライアント側のJavaScriptで取得して処理することも可能。

GETではユーザが設定したデザインや配色を伝えつつ、POSTでフォーム内容を送信するといった使い方や、GET/POSTの仕組みを組み合わせて片方を暗号化キーとして使用することなど、アイデア次第で面白い利用方法もある。


最後に…
特殊なサーバー環境やブラウザは不要で、あることも分かったと思う。


GETとPOSTは通信方法が異なる!

フォームデータのやり取りをした場合、GETとPOSTはどちらが優れているのか?

GETメソッドはPOSTより劣る!?

"GETは転送量に制限を受けるため、POSTより劣る"という意見がある。
イコール"POSTは制限がないため、GETより優れている!"という見解。

しかしGETで使用するURLの長さについて規定しているRFC2616規定では「HTTPはプロトコルとしてURIの長さを制限しない」としている。
URIとは、インターネット上に存在する情報の場所を指し示す言葉でURLはURIの機能の一部とみなせる。

なぜ制限がないのに冒頭のような話がたびたび登場するのか?
実は制限がかかっているのはHTTPの仕様ではなく、WEBサーバーもしくはクライアントであるWEBブラウザの仕様である。

代表的なWEBサーバーであるApatchは、初期設定8190バイトまでのURIを処理できる。
この制限はApatchの設定変更で更に大きくできる。

ちなみにサーバーが処理できる上限を超えたURIを受け取った場合、
「414 Request-URI Tool Long」というレスポンスを返す。

しかし一般的なWEBサイトで414レスポンスを受け取ることはまずない。
論文のような長いテキストをURLで送信する特別な場合でない限り、GETを使ってもデータ長の問題で動かないことはない。

GETは、POSTと違ってブラウザにフォームデータがそのまま表示されるため、安全面でPOSTが優れているという見解もおかしい。なぜなら、TCPモニタリングソフトを利用すれば、メッセージボディも含めて送信内容はキャプチャできる。

もし「安全性」を言及するのであれば、SSL通信を使うべきで、POSTならば安全という理由にはならない。確かに誰が使うか不明の端末で、ブックマーク表示時や履歴表示の際にURL欄にフォームデータが表示されない点では若干安全ではあるが…

一方、フォームデータが表示された方がいい場面もある。
例えば、地図の位置情報や不動産の物件検索結果などをメールで送信する場合、GETを用いてURLにフォームデータが含まれていることで利便性が上がる。

このように他者に情報を伝えることを考えれば、GETによる表示は利便性が高いことがわかる。

一方POSTで送信すれば、閲覧者側でデータを改ざんしたり、ブラウザのURL欄からフォームを経由せずに直接サーバーサイドのプログラムを呼び出したりできないメリットはある。

複数ページにわたってフォームデータを持ち続けているようなケースは、GETの場合「戻る」ボタンを使っても問題は起きないが、POSTの場合、「データを送信しますか?」というメッセージが表示される。

アンケートサイトのように、数ページを遷移して進む構成のサイトでは「途中で戻れません」と書かれていることが多いが、これはPOSTを使っているためだ。

つまりGETとPOSTは一長一短であり、「適材適所」というのが答えだ。

最後に…
もしどちらかが「優れている」のであれば、劣っている方は淘汰されているはず。
両者に生き残っているということは優劣はないということである。


前回の投稿で、HTTP通信はレスポンス送信後に
毎回切断される仕様であることがわかった。

では、切断せず…接続を継続するにはどうすればいいのか?
方法はないのだろうか?

調べてみたので、まとめてみる。

「HTTPのバージョンで決まる!!」が答え

単純明快だったので、なんの焦らしもなく、答えを書いてしまった笑。

通信において、クライアントとサーバーがどのバージョンのHTTP接続を用いているかによって変わる。

【HTTP1.0】の場合

クライアント、サーバーのいずれかが"HTTP1.0のみ"のサポートの場合がこれにあたる。
クライアントからのリクエストに対して、サーバーはHTTPヘッダーと要求されたHTMLドキュメントもしくは画像ファイルなどのバイナリをレスポンスし終えると接続が切れる。
別のページや画像が要求されると、再接続してGET命令を送り、サーバーはレスポンスが終わると切断する。

つまり必要な時に、必要な分だけ接続されるのである。

この接続方法は、インターネット全体に流れるトラフィックを減らせるだけでなく、サーバーの帯域負荷も低減できる。
一方で、毎回TCP/IPでの接続手順を繰り返すことになる為、レスポンスは低下する。

しかし!!

Connection: Keep-Alive
をHTTPヘッダーに追加すると接続を維持することができる。
英文表記そのままであるが、接続を維持せよ!という命令である。

クライアントがGETリクエストを送信する際、この指定を同時にサーバーに送り、それに対してサーバーからも"Connection: Keep-Alive"と返って来れば、接続は維持される。
接続が維持されている間は、GETなどの命令を連続で送信することができ、その都度、TCP/IPの接続が繰り返されることが起きなくなる。

また、サーバー・クライアントのいずれかが、"Connection: close"を指定するとレスポンス終了後に切断される。


【HTTP1.1】 の場合

HTTP1.1の場合、クライアント・サーバー両方がHTTP1.1対応が前提となり、
1.0と違って最初からクライアント・サーバー共に"Keep-Alive"で動作する。

よって、明示的に"Connection: Keep-Alive"をヘッダーに宣言してリクエストする必要はない。

ちなみに実際には、ブラウザは"GET / HTTP/1.1"のGET命令と同時に"Connection: Keep-Alive"を送信しているケースも少なくない。



ところで…
「HTTPのバージョンの違いって?」って思ったので、調べてみた

HTTPのバージョン差異

例えば、"GET / HTTP/1.0"というリクエストに対して、"HTTP/1.1 200 OK"と返ってきた場合、
サーバー側は1.1に対応していることがわかる。

では、"GET / HTTP/1.1"というリクエストに変えた方がいいのか??
答えは「NO」だ。

TCP/IPのモニタリングソフトで見ると、一部ブラウザはGET命令を"HTTP/1.0"で送信している。
HTTP通信には、下位互換があるため、1.1対応のサーバーに対して1.0でリクエストを送っても正しく動作する。

つまり、GET命令を送信する場合、クライアント側が1.1を指定する必要はないのである。


さて、ここまで書いておいて…なんだが、2015年に"HTTP/2"がすでにリリースされていて、
"HTTP1.1"から順次移行が進むと考えられる。

現時点で1.0はほぼ皆無だろう…

今回はHTTPバージョンの差異をしりたかったので、とりあえず1.0/1.1を対象にしてしまったが、
近々2.0についても勉強していきたいと思う。



HTTP通信の中身は、基本的にテキストベース。

ただし、テキストを使ってHTTP通信を開始するには、
TCP/IP通信でサーバーとクライアントが接続されている必要がある。

HTTPだけでは、URLからIPアドレスへの変換や、サーバーへの経路探索、
コネクションの確立などの動作はできない。

つまり、HTTPというのはTCP/IPで接続された上を、
テキストでやり取りする仕組みといえる。

メールで使われているプロトコルのSMTPやPOP3なども同様。

HTTP通信の中身を確認するためには、
  1. ブラウザとサーバー間をモニタリングする
  2. 手動でサーバーとやり取りする
がある。

ブラウザとサーバー感をモニタリングする

TCP/IPのモニタリングソフトを使ってブラウザなどのアプリケーションが
Webサーバーとどのような通信を行なっているかを確認する。

モニタリングソフトを使うと、実際に
  • ブラウザがWebサーバーに送っているリクエスト
  • Webサーバーがブラウザに返しているレスポンス
を確認できる。

モニタリングソフトは基本的にHTTだけを監視するわけではなく、
TCP/IP通信全体を監視するため、慣れるまで必要な通信を探し出すのは
少し大変かもしれない…

TCP/IPをモニタリングすることで、
「PCは想像以上に様々な通信を裏で行なっている」
ことに気づくと思う。


手動でサーバーとやり取りする

"TeraTerm"や"Putty"などのTelnetやSSHクライアントソフトを利用して行う。
接続先として、WebサーバーのURLまたはIPアドレスとポート番号「80」を指定し接続する。

そして、表示される画面上に
"GET / HTTP/1.0"
と入力して、「Enter」を入力すると、WebサーバーからレスポンスやHTTPヘッダー、
要求されたページのHTMLデータがテキストで返ってくる。

ただし、HTTPの接続は持続的な接続をしないため、サーバー側がHTMLデータの
レスポンス送信が終わると切断される。

この影響で、クライアントソフトによっては、通信終了時にウィンドウが閉じてしまう場合がある。
通信終了に閉じる機能を無効化するオプションがあれば、設定しておくことをオススメしたい。


クライアントソフトを使わずに、C#やVisual Basicなどのプログラミング言語を使って
HTTPによる通信を行う場合、ソケット通信という形でサーバーと接続し、GETなどの
HTTP命令をテキストで送信すればWEBサーバーと通信できる。


↑このページのトップヘ

-->