🍣

フロントエンドアプリケーションで HTTP リクエストのヘッダーを取得する(CSR, SSR)

2024/11/22に公開

皆さんこんにちは!Kenryu Mori です。

フロントエンド開発において、CSR, SSR について実際のところあまりイメージできていないという方って多いのではないでしょうか?(かくいう私もその一人です。。)

今回、web サーバーへの HTTP リクエストヘッダーをフロントエンドのコード側で取得するというユースケースに出会い、CSR, SSR の違いについて改めて向き合ったのでまとめてみます。

結論

早速、react 単体のアプリケーション、Nextjs, Remix の 3 つの技術スタックで実現できるのか、調べた結果は以下になります。

  • Reat : 単体では取得できない(※サーバー側でリクエストのヘッダーをクライアントに渡す API を用意するなどで実現することができるが、標準で取得する機能はない)

  • nextjs : server component または server action にてheaersを用いて取得

    import { headers } from "next/headers";
    
    export default async function Page() {
      const headersList = await headers();
      const userAgent = headersList.get("sample-header");
    
      return (
        ...
      )
    }
    
  • remix : loader, action にてheadersを用いて取得

    export async function loader({ request }: LoaderFunctionArgs) {
      const sampleHeader = request.headers.get("sample-header") || "";
      return { sampleHeader };
    }
    
    export default function TestLoaderPage() {
    const { sampleHeader } = useLoaderData<typeof loader>();
    
    return (
      ...
    );
    }
    

結論として、Nextjs や Remix などの SSR をサポートするフレームワークでは標準で機能が備わっていますが、CSR である react 単体 にはありませんでした。

なぜ react 単体(CSR)では取得できないのか

なぜ CSR で取得できないのかについてのポイントは javascript が動作する環境の違いにあります。

react 単体のアプリケーションは CSR となり、ブラウザからの http リクエストに対して初回ロード時に最低限の html と javascript が返却され、以降 javascript はクライアントサイド(ブラウザ)でのみ動作します。

しかし、javascript がユーザーが使用するブラウザで動作するということはつまり、javascript コードはユーザーに公開されており、ブラウザの開発者ツールなどを用いて閲覧や編集することができます。

したがって認証情報などの機密情報を扱うことはセキュリティ的に脆弱であり、クライアントサイドでそれらの情報にアクセスしたり操作したりするべきではないことがわかると思います。

HTTP リクエストの詳細にはそのような機密情報が付与されていることがあり、web 標準によるブラウザのセキュリティ機能によってアクセスが制限されており、一部取得することができなくなっています。
(参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers.)

一方で、nextjs や remix などのフレームワークでは SSR, CSR 両方をサポートしており、一部サーバーサイドでの処理を記述することができます。
この時 javascript は CSR の時とは違い、web サーバーの実行環境で動作します。

これはユーザーがアクセスできる環境ではないため、認証情報やデータベース等機密性の高い情報を扱うことができます。

そもそも CSR と SSR の目的の違い

CSR のようにクライアントサイドで動作する javascript は、ユーザーのアクションに応じて web ページの見た目や情報を動的に制御し、主にインタラクティブな web ページの生成を目的として実行されます。

一方、SSR のようにサーバーサイドでの処理は、ユーザープロファイルの取得や動画や膨大なトランザクション処理など、主にデータベース処理と複雑なロジックが目的となっていることが多いように思います。

このように実行環境によるモチベーションの違いを考えると、クライアントサイドで HTTP ヘッダーを取得できないこともしっくりくる気がします。

おわりに

個人的に SPA や CSR, SSR, SSG などフロントエンド開発において重要なキーワードでありながらあまり自信がないですが、言語の性質やブラウザ(クライアント)とサーバー、web 標準などの基礎的なところから振り返ることで理解が進むなと感じました。

モダンな技術にキャッチアップしていくことは大切ですが、長年使われている枯れた技術をしっかりと理解することが、結果的には近道なのかなと、、

知識不足で変なことをかいているかもしれませんが、ご容赦ください 🥺
最後まで読んでいただきありがとうございます。それでは!

Discussion