【学習記録】『HTTPの教科書』第6章~第10章　読書メモ　〜N予備校の復習を添えて〜

【学習記録】『HTTPの教科書』第3章~第5章　読書メモ　〜N予備校の復習を添えて〜( https://qiita.com/Molly95554907/items/e55d0510b081250c7259 )の続き

<h5>第６章</h5>
●HTTPヘッダーフィールド

リクエストのHTTPメッセージでも、レスポンスのHTTPメッセージでも重要な情報を持つ

・HTTPヘッダーフィールドの種類
①一般ヘッダーフィールド：res,req両方で使用されるヘッダー

②リクエストヘッダーフィールド：クライアントからサーバーに送られる際に使用されるヘッダー

③レスポンスヘッダーフィールド：サーバーからクライアントに送られる際に使用されるヘッダー

④エンティティヘッダーフィールド：エンティティの関する情報を付け加えるヘッダー

<h6>疑問</h6>
これらのヘッダーはどこでどうセットされるのか？
サーバー側のプログラミングを行い、アプリケーションを作っているプログラム側でhttpモジュールを読み込み、プログラムを作っていくということかな？
クライアント側では、Chromeの検証ツールを使ってコンソールに表示されるHTTPを見る、ということ？


<h5>第7章</h5>
●HTTPの弱点
・通信が平文なので盗聴可能。TCP/IPは盗聴可能なネットワーク
↓
通信を暗号化する（SSLなどを利用）

・誰でもリクエストすることが可能
HTTPは、誰であれリクエストを送るとレスポンスを返す。

・なりすましたサーバーにリクエストを送るリスク
・なりすましたクライアントにレスポンスを送るリスク

↓
SSLの証明書を使って認証

・完全性を証明できないので改竄可能
↓
SSLの認証を使う

※常にHTTPSを使わない理由
↓
HTTPSの暗号通信や認証にかかるコストを節約する為

<h5>第８章</h5>
●HTTPで使う認証
→誰がアクセスしているか確かめる

・Basic認証
※多くのwebサイトで求められているセキュリティレベルには足りていないのでそれほど使われていない。実証の大半はフォームベース認証だが、実装はwebサイトごとにまちまち。フォームベース認証では一般的にCookieを利用する

<h5>N予備校３章１７項「認証で利用者を制限する」</h5>
・Basic認証
ヘッダの Authorization というヘッダの 値に、 エンコードされた ID とパスワードを含めて通信することで認証する方式

・他のメジャーな認証： Cookie というヘッダを利用した認証や、 OAuth 認証 と呼ばれる方式

Basic認証を行うためのライブラリ：http-authパッケージ

```js

'use strict';
const http = require('http');
const pug = require('pug');
const auth = require('http-auth');
const basic = auth.basic(
  { realm: 'Enquetes Area.' },
  (username, password, callback) => {
    callback(username === 'guest' && password === 'xaXZJQmE');
  });
const server = http.createServer(basic, (req, res) => {
  console.info('Requested by ' + req.connection.remoteAddress);
```
HTTP,PUGモジュール,http-authモジュールの読み込み。

basic 関数に、オブジェクトと無名関数を渡している。
オブジェクトの realm プロパティは、Basic 認証時に保護する領域を規定する文字列。
無名関数では、指定された呼び出し方でユーザー名とパスワードを設定している。

http.createServer の第一引数に basic オブジェクトを渡し、 Basic 認証に対応させて server のオブジェクトを作成。

↓

ページにアクセスすると、認証が求められる。
ここでは、指定されたユーザー名とパスワードである「guest」「xaXZJQmE」を入力すると認証される。

※
デベロッパーツールの「Network>Headerタブ」で、HTTPのヘッダーとその中身を見ることができる！


<h5>第９章</h5>
HTTPに機能を追加するプロトコル
●Ajax
Asynchronius JavaScript + HTMLの略。JavaScriptのDOM（Document Object Model)操作などを活用し、webページの一部を書き換えることができる。

コア技術：XMLHttpRequesrというAPI。JavaScriptでサーバーと通信できるようになる。


<h5>N予備校4章８項「AJAX」</h5>
・ブラウザ上の JavaScript からサーバーへ非同期の HTTP リクエストを行い、 その結果を使ってユーザーインタフェースの更新を行う。

・フォーマットにはJSONを用いることが多い。

・AJAXには同一生成元ポリシーが適用され、生成元 (Origin) が異なるリソースにはアクセスすることができない。

この生成元 (Origin) は、

ホスト
スキーム
ポート
の 3 種類が一緒かどうかで判定する。

・サーバーからのデータを受け取り、 動的に HTML コンテンツを変更する


<h6>・WebSocket</h6>
・WebSocketは、Webサーバーとクライアントが一度接続を確定した後の通信を全て専用プロトコルで行うことで、JSONやHTMLなどの任意のデータを送る。

・WebSocketを使うことで、サーバーとクライアントのどちらからも送信が可能になる

・サーバーからクライアントにデーアをプッシュする機能＝サーバープッシュ機能。サーバー側はクライアントからのリクエストを待たずにデータを送れる。




<h5>N予備校4章９項「WebSocket」</h5>
WebSocketでは、よりリアルタイムな通信を、少ないコストで実現できる。

ただし WebSocket では、接続を維持したままでないといけないため、 再接続の仕組みや、サーバーへのアプリケーションのデプロイ、 そして大人数がアクセスできるようにするための仕組みなど、 特別な工夫も必要。

・WebSocketを利用するためのライブラリ：Socket.IO

●サーバー側の実装


```js

var io = require('socket.io')(server);
var os = require('os');

function emitServerStatus(socket) {
  socket.emit('server-status', { loadavg: os.loadavg() });
  console.log('server-status event emitted.');
}

io.on('connection', function (socket) {
  setInterval(emitServerStatus, 10, socket);
});
```

sosket.ioモジュール、osモジュールを読み込む。
var ioの第二引数(server)は、オブジェクトをhttpモジュールの中のhttp.Servrtオブジェクトからとってこい、ということ。

emitServerStatus 関数は、 server-status という名前で定義されるイベントを、 WebSocket の接続に対して発行する。

socket.emit関数は、文字列で定義したイベントをデータと共に発行することができる関数。（socket.ioの公式ドキュメント： https://socket.io/docs/server-api/#socket#emit(name:string%5B,-%E2%80%A6%5D):socket ）

イベント発行後にコンソールに「server-status event emitted.」を出す。

websocketの接続が確立したら、 setInterval 関数を利用して、 10 ミリ秒ごとに emitServerStatus 関数を呼び出す

↓
サーバーを起動したら、１０ミリ秒ごとにロードアベレージが表示されてたらOK



●クライアント側の実装

```js

import io from 'socket.io-client';
const socket = io('http://localhost:8000');
socket.on('server-status', (data) => {
  loadavg.text(data.loadavg.toString());
});
```
WebSocket のオブジェクトを、 socket.io-client モジュールから読み込み、 http://localhost:8000 に接続する

WebSocket の接続上で、 server-status という文字列で定義される イベントが発生した場合、そのデータを受け取って、 jQuery オブジェクトを利用して 段落の中の文字列を、受け取ったデータで更新する


<h5>第10章</h5>
<h6>・JSON</h6>

JSONとは、単純で軽いデータ表記言語。JavaScriptにおけるオブジェクト表記法を元にしている。

<h5>N予備校３章１０項「例外処理」</h5>

JSON は、すでに todo パッケージの中にある package.json でも利用されていますが、データを表す文字列の形式の一つです。
JavaScript Object Notation の略称で、 JavaScript におけるオブジェクトと同じ記法で書かれたテキスト情報です。

```js
const fs = require('fs');
const fileName = './tasks.json';

/**
 * タスクをファイルに保存する
 */
function saveTasks() {
  fs.writeFileSync(fileName, JSON.stringify(Array.from(tasks)), 'utf8');
}
```

JSON.stringify（）メソッドは、JavaScriptオブジェクトを文字列に変する。

Array.from()メソッドはArray、配列のようなオブジェクトまたは反復可能なオブジェクトから新しい浅いコピーのインスタンスを作成します。

↓
ここでは、tesksの配列の内容を文字列に変換している。


```js
// 同期的にファイルから復元
try {
  const data = fs.readFileSync(fileName, 'utf8');
  tasks = new Map(JSON.parse(data));
} catch (ignore) {
  console.log(fileName + 'から復元できませんでした');
}
```

JSON.parse()メソッドはJSON文字列を解析し、文字列で記述されたJavaScript値またはオブジェクトを構築します。

この構文は try-catch 文。

try-catch 文は、 try の宣言のあとの { } で囲まれた処理でエラーが発生した場合に、 catch ( ) のあとの { } で囲まれた処理に移動してそちらの処理を実行するという動きをします。

なお catch 句のあとの ( ) に渡された引数には、発生したエラーが渡されます。この構文のことを try-catch 文 と呼びます。

ここでは、readFileSync エラーが発生した場合、console.logが実行される。