初心者によるWeb入門

#Web
　Web「World Wide Web」
　インターネットを介して文書を公開・閲覧するためのシステム
　Web上の文書(Webページ)は、**HTML**に代表される**ハイパーテキスト**と呼ばれる言語で構成されていて、
　表示させたい文章や画像を挿入して自身のコンテンツを魅力的に発信することができる。
　**Webの特徴**
　　他のハイパーテキストへの参照(**ハイパーリンク ＜ａ＞**)を挿入することで繋がることができる。

#HTML
　HTML「HyperText Markup Language」
　ハイパーテキストを記述するための言語
　文章の表示方法やハイパーリンクを、タグを使用して既述する「`マークアップ言語`」

#Webブラウザ
　ハイパーテキストの意味を解釈し、人にとって読みやすい内容に作り変えて表示するプログラム
　WWW登場当時のWebブラウザは、現在のように画像や動画を含めて表示ができず、テキストのみで表現するもの(Lynxというブラウザ)で、画像などは別のウィンドウで表示されていた。
　現在のように文字と画像を混在させて表示できるNCSA Mosaicというブラウザが1993年に開発され、無料で公開されたため、Webの利用が広がった。

#URL(Uniform Resource Locator)
インターネット上のコンテンツを一意に指定するための仕組み。

**[URLの構成]**

http://www.host.jp/webtext/index.html

|http:|//|www.host.jp|/|webtext/index.html|
|:--|:--|:--|:--|:--|
|スキーム||ホスト名||パス名|

##URLとURIとは
|名称|説明|
|:--|:--|
|URI(Uniform Resource Identifier)|URLとURNの総称|
|URL(Uniform Resource Locator)|リソースの場所を示す|
|URN(Uniform Resource Name)|リソースの名前を示す|


##スキーム
スキームは、コンテンツを取得するための方法を表す。
httpのほか、主なものは以下

|スキーム名|説明|
|:-:|:--|
|https|暗号化されたhttp通信を表す|
|mailto|電子メールの宛先を表す|
|ftp|FTPプロトコルによる入手を表す|
|file|ファイル・システム中のファイルやディレクトリを参照する|

##ホスト名
コンテンツが存在するコンピュータ(ホスト)名を表す

www.host.jp

|www|.|host.jp|
|:--|:--|:--|
|ローカル名||親ドメイン名|

・ローカル名は自由に決めることができる。
・親ドメイン名は、インターメット上の一意性を担保するために、日本レジストリサービス(JPRS)という会社が管理している。

##パス名
ホスト名で指定されたコンピュータ上のコンテンツの位置を示す

#IPアドレス
　インターネットに接続されたすべてのコンピュータは**IPアドレス**という数値によって識別されている。
　
　**192.168.0.1**
　IPアドレスは、上記のように`ピリオドで区切られた4組の数字`で表される。
　それぞれの数字は0〜255の256通りあるため、256の4乗で、4,294,967,296通りの数値を表すことができる。

　IPアドレスは、ドメインと同じように特定の団体が管理している。
　インターネット・サービス・プロバイダ(ISP)がまとまった数のIPアドレスを確保しており、私達がインターネットを利用する際は、接続するたびに、ISPが確保しているIPアドレスのうちの1つを一時的に割り当てられる仕組みになっている。

#グローバルIPアドレスとプライベートIPアドレス
　ISPによって割り当てられるIPアドレスは、インターネット上で一意のアドレスとなり、**グローバルIPアドレス**という。
　インターネットに接続されていないオフィスや家庭内などの**プライベートネットワーク**には、グローバルIPアドレスを使用する必要はないため、ある一定範囲のIPアドレスをプライベートネットワークで自由に利用できるよう予約した**プライベートIPアドレス**を使用できる。
　プライベートIPアドレスは、下記の3種類の範囲が用意されており、この範囲のアドレスであれば、特に申請を出さずとも組織の中で自由に利用できる。

|プライベートIPアドレス|クラス|利用可能な数|
|:-:|:-:|:-:|
|10.0.0.0 〜 10.255.255.255|クラスA|16,777,216個|
|172.16.0.0 〜 172.31.255.255|クラスB|1,048,576個|
|192.168.0.0 〜 192.168.255.255|クラスC|65,536個|

※利用できるアドレスの数ごとにクラスが名付けられていて、クラスCがよく利用されている。

#DNS(Domain Name System)
　インターネット上では、前述のIPアドレスで通信相手のコンピュータを識別しているが、ブラウザのアドレスバーにあるドメイン名から、IPアドレスへ変換する仕組みをDNSという。
　ドメイン名とIPアドレスの対応表を持ったコンピュータがインターネット上にあり、DNSサーバへ問い合わせることでドメイン名に対応するIPアドレスの確認が　できると言う仕組み。

#TCP/IP(Transmission Control Protocol/Internet Protocol)
　ネットワークで情報をやり取りするための基本となるプロトコル
　TCP/IPは、ブラウザから受け取ったHTTPリクエストなどの情報を**パケット**という小さな単位に分割して送信し、
　受け取った側でそれらを元のように組み立ててからWebサーバなどのアプリケーションに渡す。

#ポート番号
　TCP/IPによって情報を受け取るアプリケーションは必ず**0〜65,535までの数字で表される**「待ち受けポート」を決めて情報を待つ。同じポートを複数のアプリケーションが利用することはできない。
　`HTTPプロトコルでは、標準で使用するポート番号が80番`と決まっているため、ブラウザでのアクセスの際にポート番号まで指定する必要がない。
　代表的なプロトコルで使用されるポートは**ウェルノウンポート(well-known ports)**と呼ばれており、下記のような物がある。

|ポート番号|プロトコル|
|:-:|:-:|
|20,21|FTP(ファイル転送)|
|22|SSH(暗号化されたリモートコンピュータとの汎用通信)|
|23|Telnet(リモートコンピュータとの汎用通信)|
|25|SMPT(メール送信)|
|53|DNS(ホスト名解決)|
|80|HTTP(Webブラウジング)|
|110|POP3(メール受信)|
|443|HTTPS(暗号化されたHTTP)|

#サーバー
　サービスや機能を提供する側のコンピュータ

#クライアント
　サービスを要求する側のコンピュータ

#Webサーバー
　ブラウザからアクセスするホームページ等のファイルがおいてあるサーバー。
　Webブラウザからコンテンツ(HTML)の要求(**リクエスト**)があると
　適したコンテンツをネットワークを通じてWebブラウザに返却(**レスポンス**)する
　他にも、要求されたコンテンツが存在しない場合は、「存在しない」というメッセージを返したり、
　別のWebサーバーに要求するよう案内する(リダイレクト)役割をする
　Webサーバーの例)
　・Apache HTTP Server
　・IIS(Internet Information Service)
　・Nginx

#プロキシ
　Webブラウザの身代わり的な存在
　クライアント(Webブラウザ)とサーバーの間に
　クライアントからのリクエストをプロキシからサーバーにリクエストして、サーバーからのレスポンスを受け取り、クライアントにわたす
　クライアント側の身元を隠せる

・リバースプロキシ
　Webサーバーの身代わり的な存在
　クライアント(Webブラウザ)とサーバーの間で、
　クライアントからのリクエストをリバースプロキシが受けサーバーに伝えて、サーバーからのレスポンスをリバースプロキシがクライアントにわたす
　Webサーバー側の身元を隠せたり、複数のWebサーバーの処理をまとめたりできる
　

#HTTP
　HTMLをやり取りする通信をするための取り決めのこと。
　WebブラウザとWebサーバーは、インターネットを通じてコンテンツのやり取りを行っている。
　このやり取りの`手段`と`メッセージの書式`は`世界共通のルール`で
　「**HTTP(HyperText Transfer Protocol)**」と呼ばれている
　HTTPでは、主に以下の定義がされている
　・ハイパーテキストの要求順番
　・ハイパーテキストの送信手順
　・要求されたハイパーテキストが存在しなかった場合の応答方法
　・Webサイトが移転したことをWebブラウザに伝える方法
　...etc

##HTTPリクエストの内容

|内容|例|説明|
|:-:|:--|:--|
|Request Method|GET|リクエストの種類を示す|
|Accept-Language|ja|クライアントが受け取る事ができる自然言語の種類を示す|
|User-agent|Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Mobile Safari/537.36|利用しているWebブラウザの種類やバージョンを示す|
|Content-Type|text/html|クライアントが受け取ることができるcontent-typeを指定|


##HTTPレスポンスの内容

###ステータス・ライン
　HTTPレスポンスを、以下のように３つの情報からなる構成で表す。

**HTTP/1.1 200 OK**

|HTTP/1.1|200|OK|
|:--|:--|:--|
|HTTPバージョン|ステータス・コード|レスポンス・フレーズ|
|使用しているプロトコルのバージョン|リクエストが成功したのかどうかを示す|ステータス・コードと同じ意味だが、人間がみてすぐ分かる内容になっている|

###ステータス・コード

|ステータス・コード|意味|説明|
|:-:|:-:|:-:|
|1xx|Informational(情報)|リクエストの処理が継続していることを表す|
|2xx|Success(成功)|リクエストが成功したことを表す|
|3xx|Redirection(リダイレクション)|リクエストを完了させるには、さらに動作が必要であることを表す|
|4xx|Client Error(クライアント・エラー)|クライアント側に起因するエラーのため、リクエストが失敗したことを表す|
|5xx|Server Error(サーバ・エラー)|サーバ側に起因するエラーのため、リクエストが失敗したことを表す|

###主なステータス・コード
|ステータス・コード|意味|説明|
|:-:|:-:|:-:|
|200|OK|リクエストが正常に完了したことを表す|
|302|Found|リクエストされたリソースが一時的に別のURIに属していることを表す。|
|401|Unauthorized|ユーザ認証に失敗したことを表す|
|403|Forbidden|アクセス権限がないため、サーバにリクエストの実行を拒否されたことを表す|
|404|Not Found|リクエストURIに一致するリソースを見つけられなかったことを表す。<br>ブラウザに入力したURLが誤っていたときのエラー|
|500|Internal Servier Error|CGIプログラムなど、サーバ内部のプログラム実行においてエラーが発生したことを表す|

##HTTPのリソース取得は1度のリクエストで1つずつ
　画像が含まれたHTMLを解析する場合、1回目のリクエストで、指定されたURLにあるHTMLファイルをリクエストする。
　ブラウザはHTMLを解析する過程で、imgタグのsrc属性に指定されたURLにある画像を取得するため、2回目のリクエストを行う。
　※一度のリクエストで1つのリソースしか取得できないため、複数の画像が含まれたページでは画像の数だけHTTPリクエストが発行されている。

##FTP(File Transfer Protocol)
　ファイル転送のためのプロトコル

##SMAP(Simple Mail Transfer Protocol)
　メール転送のためのプロトコル


#Webページが表示される流れ
　Webページを表示する際、ブラウザのアドレスバーに
　「**URL(Uniform Resouce Locator)**」を指定する
　URLには、`「どのやり取りの手順で」「どのWebサーバーに」「どのコンテンツを」`
　取得しに行くかという情報が含まれていて、
　Webブラウザはこの情報をもとに要求を送る。
　要求を受け、Webサーバーは指定されたURLをもとに指定されたやり取りの手順で
　コンテンツ(ハイパーテキスト)をWebブラウザに転送する
　
　※1度のコンテンツ転送で送られるファイルは`1つまで`
　　例えば、cssや画像ファイルが必要なWebページを表示するためには
　　①ファイル名.htmlを取得
　　②style.cssを取得
　　③画像名.jpgを取得
　　することになる。

#静的ページ
　何度アクセスしても毎回同じ内容が表示されるWebページ
　HTMLのみで記述されたWebページは静的ページ

#動的ページ
　アクセス状況に応じて異なる内容が表示されるWebページ
　動的ページの例(検索結果ページ)
　①クライアントから検索の要求
　②サーバーで検索処理を実行し、HTMLを作成
　③生成したHTMLをクライアントへ送信
　のようなページ

#CGI
　CGI(Common Gateway Interface)
　動的にHTMLを生成するために、
　WebサーバーがWebブラウザからの要求に応じてプログラムを起動させるための仕組み
　CGIから呼び出されるプログラムは「**サーバーサイド・スクリプト**」ともよばれ、
　PHP、Perl、Ruby、Python、JavaScript(Node.js)などの
　`文字列の扱いに長けたスクリプト言語`が多く使用される
　
#Servlet
　CGIで主に利用されていたPerlが、大規模システムの開発に不向きだったこと、
　Webブラウザからリクエストが届くたびにCGIを通してプロセスを起動していて、アクセスが多いと、処理が追いつかなくなるという問題があった。
　そこで、大規模システム開発がしやすいJavaで、Webアプリケーション開発をサポートするためのServletが提供される様になった。
　JVM(Java Virtual Machine)上で動作するプログラムのため、JVMが動作するコンピュータ上であれば、特定のOSやハードウェアに依存せずに動作するという利点がある。

#JSP
　Servletでは、複雑なプログラムになるほど、修正がしにくい、HTMLが分かりづらいなどの欠点があった。
　その欠点を補うため、JSPが生まれた。Servletは言わば、Javaコードの中にHTMLを埋め込む仕組みだったが、
　HTMLの中にJavaのコード(スクリプトレット)を埋め込むような仕組み。

#Webアプリケーションフレームワーク
　非常に大規模なWebアプリケーションが開発されるようになると、JSPやServletを使用しても、コーディング量が莫大になり、さらに多数の開発者がそれぞれライブラリやクラスを作成することにより、個々が実装したシステムの結合がうまく行かなかったりする問題が起こり始めた。
　大規模アプリケーションを効率的に開発するため、プログラムを再利用することで、アプリケーションを開発しやすくするような土台として、アプリケーションフレームワークが作られた、利用されるようになった。

#GETとPOST(HTTPでどのような情報がやり取りされるか)
##GETメソッドによるパラメータ渡し
```html
<form action="do_calc_get.php" method="get">
  <input type="text" name="arg1" size="8">
  +
  <input type="text" name="arg2" size="8">
  
  <input type="submit" value="計算">
</form>
```

HTMLのフォームで、サブミットボタンを押下すると、ブラウザはform要素のaction属性で指定されたURLにアクセスする。
このときのデータの受け渡し方法を指定するのがmethod属性であり、上記では「get」を指定しているため、GETメソッドを使ってフォームの入力内容を送信することを指定している。

ａｒｇ1、arg2のフォームにそれぞれ123、456を入力し、サブミットボタンを押下してdo_calc_get.phpにアクセスすると、URLは以下のようになる。

```
/do_calc_get.php?arg1=123&arg2=456
```
「?」より後ろの文字列は、**クエリ文字列**といい、フォームに入力された文字列などをWebサーバへ渡すために使用されている。
クエリ文字列は「&」で区切られており、それぞれ「**パラメータ名**=**値**」の形式で表されており、
Webサーバへ情報を送信している。

Webサーバ側では、受け取ったリクエストの中に「?」が存在すれば、それ以降をクエリ文字列として認識し、そこに含まれるパラメータをCGIなどで起動されるアプリケーションへ渡す。

###アプリケーション側でのパラメータ受け取り(PHPの場合)
```php:GETの場合(PHP)
<?php
  $arg1 = $_GET['arg1'];
  $arg2 = $_GET['arg2'];
  $result = $arg1 + $arg2;
```
PHPでは、＄_GETという連想配列にパラメータ名と値が格納されるので、
上記では＄arg1と、＄arg2の変数にそれぞれ受け取ったパラメータを代入して使用している。


###GETメソッドのデメリット
　GETリクエストによるパラメータ渡しでは、クエリ文字列によって、どのような情報をWebサーバに送信したのかが第3者に漏洩しやすい。
　・通常Webサーバでは、受け取ったリクエストのリクエスト・ライン(クエリ文字列がついたURLも含まれている)がログとして記録されるため、重要な情報をGETメソッドで送った場合、サーバーのログから重要な情報を知られてしまう危険性がある。
　・過去に作られたWebサーバでは、利用できるURLの長さが255文字に制限されているものがあり、それらを使用する場合あまり多くの情報を扱えないという問題がある。
　※GETメソッドにはメリットもある。

##POSTメソッドによるパラメータ渡し
　POSTリクエストの場合、パラメータはメッセージ・ボディに入るため、ブラウザのアドレスバーに表示されることがなく、Webサーバのログに記録される可能性も少ない。
　また、メッセージ・ボディには、長さの制限がなく、パラメータが多い場合でも心配がない。

###アプリケーション側でのパラメータ受け取り(PHPの場合)
```php:POSTの場合(PHP)
<?php
  $arg1 = $_POST['arg1'];
  $arg2 = $_POST['arg2'];
  $result = $arg1 + $arg2;
```
＄_POSTという連想配列にパラメータ名と値が格納される。

##GETとPOSTどちらを使うか
GETメソッドでは、URLにパラメータが含まれるため、パラメータごと記憶したり、人に伝えるのに便利なため、googleを始めとした検索システムに使用されている。

||GETリクエスト|POSTリクエスト|
|:--|:--|:--|
|利用するメソッド|GETメソッド|POSTメソッド|
|パラメータの格納場所|URL|メッセージ・ボディ|
|セキュリティ|低い(URLが他人に見られる/Webサーバのログに残る)|比較的高い(Webサーバのログに残らないことが多い)|
|パラメータの長さ|古いソフトウェアではURLが255文字以内に制限される場合がある|制限なし|
|パラメータの保存・再現|しやすい|しにくい|
|副作用が発生しないこと|期待される|期待されない|

　機密情報を送信する場合や、決済処理などの副作用を伴う処理、大量の情報を送信する必要がある場合はPOSTメソッドを使用すべき。
　それ以外で、副作用がない処理の場合はGETメソッドを使用すると、パラメータごと保存するというメリットを活かせる。

#日本語のパラメータの渡し方(パーセントエンコード)
　URLで利用できる文字には制限があり、クエリ文字もURLの一部のため、日本語や半角スペースなどをURLに使用する事はできないが、ブラウザ側で自動的にURLで使用できない文字を「%」から始まる16進数の文字列に変換される。
この変換を**パーセントエンコード**という。

　**URLで利用できる文字**

|||
|:--|:-:|
|半角大文字アルファベット|A 〜 Z|
|半角小文字アルファベット|a 〜 z|
|半角数字|0 〜 9|
|ハイフン|-|
|ピリオド|.|
|アンダースコア|_|
|チルダ|~|


※副作用がない:同じ要求を何度繰り返しても同じ結果が得られること