メインコンテンツまでスキップ

HTTP(HyperText Transfer Protocol)

Overview

HTTP(HyperText Transfer Protocol)はサーバとクライアント(ブラウザ)の間でウェブページを送受信するためのプロトコル。
また、World Wide Web上の通信方法を示すものであり、この通信はクライアントからサーバーへのリクエストとサーバーからクライアントへのレスポンスで構成される。 こうしたHTTPリクエストとHTTPレスポンスには、ヘッダーーと呼ばれる一連のキーと値のペアが追加される。

HTTP自体は**ステートレス(状態を保持せず1回で完結すること)**なプロトコル
リクエスト (GET) => レスポンス (200 OK ...) で手続きが完結。
SMTPのように複数の手続きを踏む必要はなく、その時の状態も保持していない。

HTTP 歴史

現在最新のversionは1.1
1.1になる前には0.9と1.0の2つのバージョンが存在していた。
また1.1の後継もある。
※0.9に関しては仕様書は存在しない。Berners-LeeがWebを発明していたときのプロトコルが呼ばれている。

  • 0.9 : headerがなかった
  • 1.0 : IETFが標準化された最初のバージョン(POST対応)
  • 1.1 : HTTPの完成(バーチャルホスト対応)
  • 2.0 : 2015年ほど

チャンク転送・Acceptヘッダーによるコンテントネゴシエーション・複雑なキャッシュコントロール、持続的接続などの機能。

1.1以降も議論が続けられているが、HTTPそのものの価値をRESTアーキテクチャスタイルに見出した結果、HTTP1.1を有効に活用していこう。
というのが現代的な開発スタイルとなっている。

参考

リファレンス(一番わかりやすい)
HTTP入門
冪等性について
ブラウザからサーバまでわかりやすい
プロトコル
HTTPの仕組み再入門 普及が進む「HTTP/2」の仕組みとメリットとは

HTTP仕組み

BASEとなっているのはTCP/IP
これをみて参考にする(一番いいためまとめる)

HTTPリクエストの種類

Form: 同期通信

  • 説明: HTMLフォームを使用して送信されるリクエスト。通常、ページが再読み込みされる。
  • 特徴:
    • デフォルトでは、ページがリロードされる同期通信。
    • データはURLエンコードされて送信される。
    • サーバーからのレスポンスに基づいてページが更新される。

XMLHttpRequest (XHR): 非同期通信(CORS対象)

  • 説明: JavaScriptを使用して非同期にサーバーと通信するためのオブジェクト。
  • 特徴:
    • 非同期通信をサポートし、ページの一部を更新できる。
    • CORS(Cross-Origin Resource Sharing)の制約を受ける。
    • レスポンス形式としてXML、JSON、HTML、テキストなどを扱える。
    • 同期通信も可能だが、推奨されない。

Fetch: 非同期通信(CORS対象)

  • 説明: モダンなJavaScript APIで、XHRに代わるものとして設計された。
  • 特徴:
    • 非同期通信をサポートし、Promiseベースのインターフェースを提供。
    • CORSの制約を受ける。
    • よりシンプルで直感的な構文。
    • レスポンスをストリームとして扱えるため、部分的なデータ取得が可能。

JSONP

  • 説明: JSON with Padding。クロスドメインリクエストを行うための古い方法。
  • 特徴:
    • <script> タグを使用してリクエストを送信する。
    • サーバーがJavaScriptの関数をラップしたJSONを返す。
    • 主にGETリクエストに使用。

AJAX(Asynchronous JavaScript and XML)

  • 説明: 非同期通信の総称。XMLHttpRequestやFetchを用いた通信方法を指す。
  • 特徴:
    • サーバーと非同期でデータのやり取りをする。ページの一部を更新できる。
    • リクエストは非同期で行われるため、ページのリロードが不要。
    • JSON、XML、HTMLなどさまざまな形式のデータを扱える。

通常のHTTPリクエスト

  1. ブラウザがHTMLをリクエストする
    • ユーザーがブラウザでURLを入力するか、リンクをクリックする。
    • ブラウザはDNSサーバにアクセスし、ドメイン名をIPアドレスに解決する。
    • そのIPアドレスに対して、HTTPリクエストを送信する。
  2. サーバがリクエストを受け付け、DBに問い合わせをしHTMLを生成
    • サーバがリクエストを受信する。
    • リクエストに基づいて必要なデータをデータベースから取得する。
    • データを基にHTMLを生成し、レスポンスとしてブラウザに返す。
  3. ブラウザがHTMLを受け取る
    • ブラウザがサーバからのレスポンスを受信する。
    • レスポンスのHTTPステータスコードを確認し、成功(200 OK)などを確認する。
  4. HTMLのパースを開始
    • ブラウザは受け取ったHTMLドキュメントのパースを開始する。
  5. JavaScriptやCSS、フォントや画像などのアセットをリクエスト
    • HTML内のリンク(<link> タグ)、スクリプト(<script> タグ)、画像(<img> タグ)などを解析し、それらのアセットのリクエストを順次行う。
  6. ブラウザがアセットを受け取る
    • 各アセットのリクエストに対するレスポンスを受け取る。
    • ※キャッシュが有効な場合、ブラウザはキャッシュからアセットを取得することもある。
  7. アセットのパース
    • 受け取ったCSS、JavaScript、画像などのアセットをパースし、適用する。
    • JavaScriptの実行やCSSによるスタイルの適用が行われる。
  8. HTMLのレンダリングが完了する
    • 全てのアセットがロードされ、パースが完了すると、ブラウザは最終的なレンダリングを行います。
    • ユーザーは完全にレンダリングされたウェブページを閲覧できるようになる。

補足

  • キャッシュの利用: ブラウザはリソースの再取得を避けるために、キャッシュされたコンテンツを利用する場合があります。
  • 非同期リクエスト: AJAXリクエストなど、ページがロードされた後にJavaScriptが追加のリソースを非同期でリクエストすることもあります。

JSやCSSなどアセットのリクエストはレスポンスを受診しHTMLのパースが始まったタイミングで実行される。
そのためHTMLのパースがどんなに早く終わってもアセットのダウンロード待ちが発生してしまうと全体の描画を効率化するためにはアセットのリクエストをもっと早くするべき。

アセットのロード開始タイミングを早める

HTTPにはpreloadという仕組みがあり、HTTPレスポンスヘッダーやHTMLのタグ中にこのアセットを先にロードしてくださいと指定ができる。
レスポンスヘッダーに次の要素を追加する。
このヘッダーを受け取るとブラウザはHTMLを取った直後、HTMLをパースする前にアセットのリクエストを開始できる。

HTTP 1.1

バーチャルホストなどに対応した「HTTP/1.1」が策定された。 HTTP/1.1ではクライアントが複数のリクエストを同時に送れるようになったが、その場合も必ずリクエストされた順でレスポンスを返すようになっている。
そのため、たとえばレスポンスとして容量の大きいファイルを返す場合や、レスポンスを返すための処理に時間がかかるような場合でも、後続のレスポンスは先のレスポンスの送信が完了するまで送信できない。
そのため、多くのWebブラウザではWebサーバーに対して同時に複数のコネクションを確立することとで、並行してコンテンツをダウンロードできるよう実装されている。

Image from Gyazo

HTTP 2.0

HTTP/2は従来のHTTPを踏襲しつつも、新たな転送手段を提供することで既存の問題点を解決し、より少ない通信量でより迅速にやり取りを行えるようになっている。
HTTP/2の最大の特徴はストリームという概念を導入したこと。
これによって1つのコネクション内で同時に並行して複数のリクエスト/レスポンスを処理できるようになった。

Image from Gyazo

HTTPの仕様ではステータスコードが決まるまでレスポンスを返せなかった。
つまり、application.jsを利用することが自明だったとしてもWebアプリケーション自身がレスポンスを返すまでは待つ必要がありました。 これを解決するのがEarlyHintsと呼ばれる仕様。 ステータスコード103として、本来のレスポンスを送る前に、リソースのヒントを送ることができます。

  • 上記で起きた他の言語影響
    • 主要なブラウザが軒並みES6をサポートした事により、 ES6で書かれたコードをトランスパイルすることなく、そのまま動作するようになったこと。
    • HTTP/2が普及したことによりwebpackでファイルを結合するメリットが薄れたこと。

HTTP 3.0

N/A

HTTPでサーバへデータを渡す

HTTP内でのクライアント

今回POSTメソッドについて言及しましたが、HTTPプロトコル(rfc2616)では、メッセージボディをセットできるメソッドについては特に言及していないため、POST以外のメソッド(たとえばGETメソッド)でもメッセージボディをセットすることはできます。 ですが、ブラウザからGETメソッドでリクエストを送信する場合、通常はメッセージボディではなくHTTPパラメータとして設定されます。 このため、サーバー側の処理としてGETメソッドの処理ではメッセージボディに何かデータが設定されてくるということは一般的には期待しません。

クエリパラメーター

?以降のフォーマットに関してどういう値設計にするのかのルールはとくに明言されていない(RFC)

しかし,query構成要素はしばしば key=valueの対の形式で識別するための情報を運ぶために使用され、そこで頻繁に使用された値は別のURIの参照のため時にはそれあらの文字をパーセントエンコーディングすることを避ける方がユーザビリティのためには良い

とあるように一般論として key=value の形式であるぐらいしかRFC上では語られていない。

クエリパラメーターを配列で渡したいとき

https://stg.www.yumenographia.com/tickets/?dates=2021-10-07,2021-10-10,2021-10-11,2021-10-12

?の後に ,(カンマ) 区切りで渡す。それをserver側で配列に変換するのがひとつのやり方。

クエリパラメーター変換

numberなどで送ってもどうやらstringに変換されるっぽい。

localhostのhttps化

参考URL

閲覧ページのHTTP versionを調べる

参考URL


HTTP content negotiation(コンテントネゴシエーション)

リファレンス

HTTP においてコンテンツ交渉 (content negotiation) は、同じ URI におけるさまざまな表現のリソースを提供するために使用する仕組みであり、ユーザーエージェントはどのリソースがユーザーにもっとも適しているか (例えば文書の言語はどれか、画像形式はどれか、コンテンツエンコード方式はどれか) を指定することができます。

HTTP body-parserとは

ブラウザなどのクライアントからサーバーに対して処理のリクエストを行う際に送るメッセージメッセージボディ(Message body)という。

  • クライアントから一緒に送信するデータ。
  • クライアントからのリクエスト応答としてサーバーからクライアントへ返信するデータ。

body-parserは、このメッセージボディを解析してプログラムで参照しやすいオブジェクトに変換してくれるライブラリ。

一番わかりやすいのはPOSTメソッドを使ったフォーム情報の送信時です。 ユーザーがブラウザに表示された入力フォームにデータを入力し、「送信」をクリックしたときにPOSTメソッドでフォームデータをサーバーに送信しますが、そのときにブラウザは入力されたデータをPOSTメソッドのメッセージボディにセットして、HTTPヘッダーーに必要な情報(メッセージボディの文字数や文字コード等)を一緒にセットしてサーバーに送信します。 サーバーは、受け取った情報からメッセージボディを特定し、HTTPヘッダーーに指定された情報をもとに復元してサーバー側で処理します。

WEBサーバーとしては、この処理は定形処理といっていいぐらい、どのようなアプリケーションでも必要となることが予想される処理で、毎回個別にプログラムを書くのはあまりにもムダなのでbody-parserという拡張モジュールが担ってくれるということです。

HTTP上で認証を行う場合

参考URL

  • セッションによる認証
  • リクエストボディにトークンを含める認証
  • 独自ヘッダーにトークンを含める認証
  • Authorizationヘッダーを用いた認証(Basic, Digest, Bearer)
  • JWT認証

などがある。

Bearer認証 : bearerは担い手や使いといった意味を持つ

Authorization Bearer ヘッダを用いた認証 API の実装

Bearer認証は、トークンを利用した認証・認可に利用されることを想定しており、OAuth 2.0の仕様の一部として定義されているがその仕様内でHTTPでも使用しても良いと記述されている。

HTTPのAuthorizationヘッダーにスキームとして指定でき Authorization: Bearer <token> のようにして指定する。 トークンの形式はtoken68の形式で指定することが定められている。

Authorization ヘッダー

Authorizationヘッダーに指定できるスキームには以下がある。

  • Basic
  • Digest
  • Bearer これらのスキームはIANAによって管理されている。

token68

token68は1文字以上の半角英数字 -(ハイフン), . (ドット), _ (アンダーバー), ~ (チルダ), + (プラス), / (スラッシュ)から構成された文字列を指す. 文字列の末尾に任意個の = (イコール)が挿入されていても良い.

リクエストとレスポンスの流れ

まずクライアントから Authorization: Bearer <token> を含めたリクエストが投げられる。 それを受け取ったサーバは WWW-Authenticate: Bearer realm="XXXX" 形式を返す。 又は WWW-Authenticate: Bearer error="XXXX" 形式のヘッダーを含めたレスポンスを返す。

成功パターン とくに返したいパラメーターがない場合はrealmを空にして返す。 WWW-Authenticate: Bearer realm=""

失敗パターン リクエストにAuthorizationヘッダーが含まれていないケース(401 Unauthorized) WWW-Authenticate: Bearer realm="token_required"

リクエストパラメーターが不正なケース(400 Bad Request) WWW-Authenticate: Bearer error="invalid_request"

トークンが失効、破損しているケース(401 Unauthorized) WWW-Authenticate: Bearer error="invalid_token"

トークンのスコープが不十分なケース(403 Forbidden) WWW-Authenticate: Bearer error="insufficient_scope"

トークン保存場所

クライアント側はlocalStorageかsessionStorage。 サーバ側はDBに保存することへなる。

トークンの有効期限

トークンが漏れてしまうと第三者がそのトークンを使ってあらゆる操作ができてしまうため, 有効期限は設けておくべき。


httpとセッション

HTTPは基本的に1つのリクエストと1つのレスポンスだけで完結する。 何度リクエストを送っても前回と同じ人のリクエストだなと認識されない。 同じユーザに対して、リクエストのたびにそのユーザ用のレスポンスを返すといった仕組みを(セッション)を作るにはサーバ側で工夫が必要になる。

URLの説明

スキーム://ホスト:Port/path

Origin(オリジン)

ウェブコンテンツのオリジンOriginは、ウェブコンテンツにアクセスするために使われる。 URLのスキーム(プロトコル)・ホスト(ドメイン)ポート によって定義される。 スキーム、ホスト、ポートがすべて一致した場合のみ、二つのオブジェクトは同じオリジンであると言える。 操作によっては同じオリジンのコンテンツに限定されており、この制約は CORS を使用して緩和できる。

  • 同一オリジンの例
# スキーム (http) およびホスト (example.com) が同じなので同一オリジン
http://example.com/app1/index.html
http://example.com/app2/index.html

  • 異なるオリジンの例
# スキームが異なる
http://example.com/app1
https://example.com/app2

# ホストが異なる
http://example.com
http://www.example.com
http://myapp.example.com

# ポートが異なる
http://example.com
http://example.com:8080

クロスサイト(クロスオリジン)

スキーマ(httpやhttps)やホスト名・ポート番号のどれか1つでも異なるウェブサイトのことを「クロスサイト(またはクロスオリジン)」という。 クロスサイトな2つのサイト間では、簡単にデータがやりとりできないようになっています(セキュリティを保つため)


HTTPヘッダー

参考URL

ヘッダーはコロンで区切られたキーと値のペアで構成される。 ※値はディレクティブ(指示)と呼ばれる。

# key: 値,値
cache-control: public, max-age=14400

リクエストヘッダー

  • Accept(要求) ブラウザが受信可能なデータ形式(MIMEタイプ)をサーバに伝える。 アスタリスクはすべてを意味する。

  • Accept-Encoding 参考URL

HTTPリクエストヘッダー Accept-Encoding を理解するためには、まずはHTTP通信データの圧縮について理解する必要があります。 皆さんが普段目にしているホームページは、HTMLなどのテキストで作られていることは本ページを見られている方ならご存知でしょう。 またスマートフォンアプリなども JSON や XML などのテキスト形式でサーバーとデータの受け渡しをしています。

サーバーとの通信データ量を減らしたいと考えた場合、コンテンツの内容を変えずにそれを実現するには、データを圧縮する方法が考えられます。 テキストはバイナリなどに比べて圧縮しやすく、HTML, スタイルシート(CSS), JavaScript, JSON, XML などのWEBで利用されているテキストを圧縮して送受信すれば、通信データ量を減らすことができるというわけです。 しかし、通信データを圧縮する場合に考慮すべき点もあります。 それはクライアントとサーバーが、共通の圧縮アルゴリズムをサポートしている必要がある点です。 サーバーが一方的に圧縮されたコンテンツを送りつけても、クライアントが解凍できないと意味がありません。 またデメリットとしては、データ送信前とデータ受信後に圧縮・解凍の処理が必要になるため、平文でデータを送受信するよりも処理負荷が高まることがあげられます。

ポイント

  1. コンテンツを圧縮して送信すれば、ネットワークを流れるデータ量を減らすことができる
  2. 通信データを圧縮するには、クライアントとサーバが共通した圧縮アルゴリズムをサポートする必要がある。
  3. 通信データを圧縮した場合、データ送信前とデータ受信後に圧縮・解答の処理を行うため処理負荷は高まる。

目的
Accept-Encodingヘッダーは、HTTPクライアントがサーバーにHTTPリクエストを送信する際に付与するヘッダー項目です。
Accept-Encodingヘッダーの目的は、クライアントがサポートしている圧縮方式をサーバーに教えることです。 サーバーは送られてきたAccept-Encodingヘッダーの値を見て、クライアントに合う圧縮アルゴリズムでコンテンツを圧縮して返却してあげれば良いというわけです。

  • Allow(要求/応答) 要求URLで示すリソースに対して使用可能なメソッドの一覧を示す。下記の例ではリソースに対してGET, HEAD, PUTメソッドを使用可能であることを示す。

Allow: GET, HEAD, PUT

  • Authorization(要求) 認証が必要なリソースに対して認証情報を伝えます。たとえば、BASIC認証の場合は、Basicの文字と、ユーザ名とパスワードをコロン(:)で連結したものを BASE64形式 にエンコードしたものを転送する。

Authorization: Basic dGFuYWthOmhpbWl0c3U=


Referer(リファラー)

リファレンス

Referer リクエストヘッダーには、現在リクエストされているページへのリンク先を持った直前のウェブページのアドレスが含まれています。 Referer ヘッダーにより、サーバーは人々がどこから訪問しに来たかを識別し、分析、ログ、キャッシュの最適化などに利用することができます。

ステートフルとステートレスの比較

参考URL

前提 セッションの状態 一連のインタラクティブな操作(session)における各状態(state)のこと

ステートフル

サーバがクライアントのセッションの状態を保持しているという制約のこと 特徴:セッションの状態によってリクエストに対するレスポンスが変わる。 例:FTP, SMTP

ステートレス

サーバがクライアントのセッションの状態を保持しないという制約のこと 特徴:リクエストに対するレスポンスが変わらない。 例:HTTP

Bearer認証について

Webhookとは

参考URL

アプリケーションの更新情報を他のアプリケーションへリアルタイム提供する仕組みや概念のこと

通知する、Webhookを送るなどの言葉はPOSTリクエストのことを指している。

httpでの冪等性(べきとうせい): idempotence

冪等性とは、同じ操作何度繰り返しても同じ結果が得られるという性質

RESTfulにおける冪等性

冪等性はRESTfulの文脈でもよく話題になります。RESTfulでも冪等性の概念は同じで「同じ操作を何度繰り返しても、同じ結果が得られる」という意味。 もう少しRESTfulっぽく寄せた説明をするなら同じリクエストを何度繰り返しても、同じリソース状態になることという感じになると思います。

得られる結果というのはリソース状態であって、レスポンスではないことに注意してください。DELETEメソッドには冪等性がありますが、1度目のリクエストでは200レスポンスを、2度目以降のリクエストは404レスポンスを返すことが普通です1。このように冪等性があるAPIでも回数に応じてレスポンスが変化することがありますが、リソースが削除されたという結果(リソース状態)が2度目のリクエストで覆ることはありません。

RESTfulでは GET, PUT, PATCH, DELETEは冪等性があるメソッドとされている POSTは冪等性がない

投稿にいいねをつけるが、二度目は取り消される仕様 これは冪等性がないといえる

# POST /items/:item_id/like

冪等性のメリット 関数やAPI、コマンドを実行する側が、前提となる状態を気にしなくてよくなるという点


HTTP header

リクエストとレスポンスで分ける必要があるが両方に記載する場合があるため、どちらで使われるか必ず書くこと

# 構文
Referer: ~ # headerのkeyのあとはディレクティブという。

Content-Type

リファレンス わかりやすい Content-Type 表現ヘッダーは、リソースのメディア種別を示すために使用する(リクエストボディのメディアタイプを指定) ※GETに Content-Type は必要ない

  • application/json

  • application/x-www-form-urlencoded フォームの送信の際に、クライアントがWebサーバに送信するContent-Type名のひとつ

データはid=dataの形式で、formが複数ある場合は&で区切られる(form1=data1&form2=data2) dataはURLエンコードされる。

参考URL

withCredentials

参考URL

クロスオリジンのAJAXリクエストでクレデンシャル(クッキーの送信またはBASIC認証)を必要とする場合は、それを許可するオプションをフロント側Javascriptで付けておく必要があります。デフォルトではCORSリクエストでクッキーは送信されませんし、BASIC認証は送れません。

XMLHttpRequest.withCredentials プロパティは論理値で、サイト間のAccess-ControlリクエストがCookie、認証ヘッダー、 TLSクライアント証明書などの資格情報を使用して行うべきかどうかを示します。


referer(リファラー)

参考URL


ヘッダーーの認証

参考URL

WWW-Authenticate: 訳 認証

サーバからクライアントに向けてサーバが要求する認証の種類を知らせる働きがある。

# 機能: アクセスに必要な認証情報を知らせる

WWW-Authenticate: Basic realm="Web access"

# 認証の種類:スキーム(Basicの部分)
# Basic認証
# Digest認証

# 認証に必要な情報 realm=Web access
# Basic認証では保護空間(realm)の名前。この名前によって以前に行った検証が有効な範囲かどうかを確認できる。

Authorization: 訳 認可

クライアントからサーバに向けて認証のためのユーザ名とパスワードを知らせる働きがある。

Basic認証概要

HTTPで利用できる認証方法(認証スキーム)のうち、恐らくもっとも広く利用されているのが「Basic認証」 ここでは、Basic認証について説明します。ちなみに、Basic認証以外のものとしては、「ダイジェスト認証」(パスワードを送らないのでより安全)などがあります。 Basic認証では、Authorizationヘッダーーに、「Basic」の文字とその後に1つ空白を挟んで、ユーザー名とパスワードから生成した認証情報を指定します。 この認証情報は、「ユーザー名:パスワード」の形で、ユーザー名とパスワードをコロン(:)でつなぎ、それ全体をBase64と呼ばれる方式で変換して作成します


キャッシュとHTTPの仕様

ここでのキャッシュとは、サーバへのアクセスの頻度や通信量を減らすためにクライアント側で一度とった情報を保存しておき、再度必要になった際あらかじめ取得してあった情報を利用することを指す。

fresh(新鮮): キャッシュが利用可能な状態 stale(新鮮ではない): キャッシュが利用できない状態

静的なデータのキャッシュは遠い未来を指定するがHTTP1.1の仕様によると1年以上未来の日付を送るべきではないとされている。

キャッシュのメリット

  • サーバへの通信を減らすことができるためユーザの体感速度をあげることができる。
  • ネットワーク接続がきれあt状態でもある程度サービスを継続できる
  • サーバへの通信回数、転送量を減らすことでユーザの通信コストを下げることができる。
  • サーバへのアクセスが減ることで、サーバの維持費を抑えることができる。

キャッシュについえ考える際には中継するプロキシサーバを意識する必要がある。(レスポンスデータをキャッシュする場合があるため) 意図しないキャッシュが行われる可能性があり、正しいデータがクライアントに届かなくなる危険性がある。 そのためプロキシorリバースプロキシに対してオリジンサーバでキャッシュのコントロールをしっかり行うことで効率化が図れる。

HTTP キャッシュ仕様(2種類)

HTTPにはキャッシュの仕組みが用意されているためAPIからの利用は可能。 RFC7234で定義されている。

2種類ある。

  • Expiration Model(期限切れモデル)
  • Validation Model(検証モデル)

Expiration Model(期限切れモデル)

サーバからレスポンスを受け取ったときの情報をもとにキャッシュの時間をクライアントで決める。

つまりクライアント側で期限が切れたと判断されるまではネットワークアクセスは行われない。 期限切れモデルはあらかじめレスポンスデータに保存期間を決めておき、期限が切れたら再度アクセスをして取得を行うこと。

期限切れモデルはいつ期限が切れるかをサーバからのレスポンスに含めて返すことで実現できる。 HTTP1.1では2種類用意されている。

  1. Expiresレスポンスヘッダーー(HTTP1.0から存在するヘッダーー)
  2. Cache-Controlレスポンスヘッダーー(HTTP1.1から定義されたヘッダーー)
# 例
Expires: Fri, 01 Jan 2016 00:00:00 GMT
Cache-Control: max-age=3600

Cache-Control(Expiration Model(期限切れモデル))の一つ

Cache-Controlは現在時刻からの秒数を返す。 Cache-Controlはさまざまなキャッシュのコントロールを行うヘッダーーで max-age 以外にもさまざまな指定が可能。

Expires or Cache-Controlどっちを返す?

返すデータの性質による。 またExpiresとCache-Control両方を利用した場合にはより新しい仕様であるCache-Controlが優先される。

例(Expires) 特定の日時に更新されることがあらかじめわかっているデータ 天気情報が毎日同じ時間に更新される場合などはExpiresでその日時を指定できる。 今後更新される可能性がないデータや静的データの場合には遠い将来の日時を指定することで一度とったキャッシュをずっと保存する指示を出せる。

例(Cache-Control) 毎日何時などの定期更新ではないものの、更新頻度がある程度限られているものや更新頻度は低くないもののあまり頻繁にアクセスして欲しくない場合(たとえばリアルタイム性がそれほど重要ではない情報)に利用ができる。


Validation Model(検証モデル)

今保持しているキャッシュが最新であるかを問い合わせてデータが更新されていた場合にのみ取得を行う。 キャッシュチェックの際にネットワークアクセスが発生する。 たとえば100KBのデータをすでにクライアント側にキャッシュしているのに、まったく同じデータをダウンロードするのと、データが更新されていなかった場合には更新されていないよという情報だけを返すのとでは転送データの量が変わってくる。 したがって大きなデータをやり取りするような性格のAPIであればあるほど、キャッシュの効果が高まる。

検証モデルを行うには、条件つきリクエストに対応する必要があり**もし今保持している情報が更新されていたら情報をください。**というもの(クライアントから)に対し 更新されていた場合にのみデータを返す。更新されていなかったら304(Not Modified)というステータスコードを返す(情報が更新されていない意味)

クライアントから 条件付きリクエストを行う際に、最終更新日付とエンティティタグのどちらかを指標として用いる。 エンティティタグはある特定のリソースのバージョンを表す識別子、フィンガープリントである文字列のこと。

Preflight request (プリフライトリクエスト)

リファレンス

Content-Typeフィールドに application/json という値をセットすると、プリフライト・リクエストが発生することになる。

シンプルリクエストに当てはまらないリクエストがプリフライトリクエストとなる。
プリフライトリクエストはそもそもセキュリティのための機能ではない。
プリフライトリクエストが発生するということは、HTTPメッセージのやり取りが1回増えるということなので、パフォーマンス上、望ましくない。

  1. CORS許可してないAPIをContent-Typeをapplication/jsonでPOSTリクエストする →CORSとかプリフライトリクエストに関するエラーが出て失敗するはず

  2. CORS許可しているAPIをContent-Typeをapplication/jsonでPOSTリクエストする →プリフライトリクエストが送られるはず(つまりOPTIONSメソッドとPOSTメソッドのリクエストが飛ぶ)

Referer(リファラー)

知ってるようで知らないRefererとReferrer-Policyのお話

Refererを送っているのはwebブラウザ
ブラウザが自動でRequestヘッダーのrefererに送信元のURL情報を付与しています。

Refererが生じる脆弱性

登録ボタンを押すとメールが送信され、そのメールに以下のようなメールアドレスとパスワードが埋め込まれた

URLに情報がすでに入っていることにより、このリンクをクリックすることでメアドとパスワードを再度入力することなく、認証に成功します。 そしてサイト内に貼ってある外部リンク

もしこのサイトの運営者が悪意のある人だった場合、Referer情報から個人情報を取得し、悪用できてしまう。

どうすればこの脆弱性を回避できるでしょうか? URLにセキュアな情報を入れないようにすることは大事ですがUX向上のためどうしても入れたい場合(認証でのリダイレクトログインなど)もあるかと思います。

そんな時に登場するのがReferrer-Policyです。

Referrer-Policyの役割

Referrer-Policyは以下のようなmetaタグに設定することでrefererを送信するブラウザの挙動を変更できる。

<meta name="referrer" content="strict-origin-when-cross-origin" />

HTTP/2

普及が進む「HTTP/2」の仕組みとメリットとは

HTTP/2の最大の特徴は、「ストリーム」という概念を導入したことだ。これによって1つのコネクション内で同時に並行して複数のリクエスト/レスポンスを処理できるようになっtあ

ブラウザにおけるHTTP/2の採用について

採用のタイムライン

HTTP/2は、Hypertext Transfer Protocolの第2版であり、2015年5月にインターネットエンジニアリングタスクフォース(IETF)によってRFC 7540として正式に標準化されました。この標準が確立された後、主要なウェブブラウザはすぐにHTTP/2を実装し、サポートを開始しました。主要なブラウザによる採用のタイムラインは以下の通りです:

  • Google Chrome: バージョン40からHTTP/2をサポート(2015年1月リリース)
  • Mozilla Firefox: バージョン36からHTTP/2をサポート(2015年2月リリース)
  • Microsoft Edge: 初リリースからHTTP/2をサポート(2015年7月)
  • Apple Safari: iOS 9およびOS X 10.11からHTTP/2をサポート(2015年9月リリース)
  • Opera: バージョン28からHTTP/2をサポート(2015年3月リリース)

現在のサポート状況

現在、すべてのモダンブラウザはHTTP/2を完全にサポートしており、これはウェブ通信のデファクトスタンダードとなっています。これには以下が含まれます:

  • Google Chrome
  • Mozilla Firefox
  • Microsoft Edge
  • Apple Safari
  • Opera

HTTP/2の利点

HTTP/2は、HTTP/1.1のパフォーマンス制限を克服するために導入され、いくつかの主要な利点を提供します:

  • マルチプレキシング: 単一のTCP接続上で複数のリクエストとレスポンスを同時に送信可能。
  • ヘッダー圧縮: HTTPヘッダーのオーバーヘッドを圧縮することで削減。
  • サーバープッシュ: サーバーがクライアントにリソースを事前に送信可能。
  • ストリーム優先順位: クライアントがどのリソースがより重要かを優先順位付けすることで、読み込みパフォーマンスを向上。

ブラウザ市場とHTTP/2

ほとんどのモダンなウェブトラフィックはHTTP/2経由で提供されていますが、すべてのブラウザやユーザーエージェントがHTTP/2を同様にサポートしているわけではありません。主要なブラウザでは広くサポートされていますが、古いバージョンやニッチなブラウザはまだHTTP/1.1を使用していることがあります。

結論

HTTP/2は2015年の標準化以降広く採用されており、主要なブラウザはすぐにサポートを提供しました。現在では、すべてのモダンブラウザがHTTP/2をサポートしており、これによりHTTP/1.1に比べてウェブのパフォーマンスと効率が向上しています。

さらに詳しい情報は、各ブラウザの公式ドキュメントやリリースノート、またはCan I useのようなウェブ技術のブラウザ互換性を追跡するリソースを参照してください。