開発者ドキュメント

HTTPモジュールを使用してNode.jsでWebサーバーを作成する方法

序章

ブラウザでWebページを表示すると、インターネット上の別のコンピュータに要求が送信され、応答としてWebページが提供されます。 あなたがインターネット経由で話しているそのコンピュータはウェブサーバーです。 Webサーバーは、ブラウザーなどのクライアントからHTTP要求を受信し、HTMLページやAPIからのJSONなどのHTTP応答を提供します。

サーバーがWebページを返すには、多くのソフトウェアが関係しています。 このソフトウェアは通常、フロントエンドとバックエンドの2つのカテゴリに分類されます。 フロントエンドコードは、ナビゲーションバーの色やテキストのスタイルなど、コンテンツの表示方法に関係しています。 バックエンドコードは、データの交換、処理、および保存の方法に関係しています。 ブラウザからのネットワークリクエストを処理したり、データベースと通信したりするコードは、主にバックエンドコードによって管理されます。

Node.js を使用すると、開発者は JavaScript を使用してバックエンドコードを記述できますが、従来はブラウザーでフロントエンドコードを記述して使用されていました。 このようにフロントエンドとバックエンドの両方を一緒に使用すると、Webサーバーの作成にかかる労力が軽減されます。これが、Node.jsがバックエンドコードを作成するための一般的な選択肢である主な理由です。

このチュートリアルでは、Node.jsに含まれているhttpモジュールを使用してWebサーバーを構築する方法を学習します。 JSONデータ、CSVファイル、およびHTMLWebページを返すことができるWebサーバーを構築します。

前提条件

ステップ1—基本的なHTTPサーバーを作成する

プレーンテキストをユーザーに返すサーバーを作成することから始めましょう。 これは、サーバーのセットアップに必要な主要な概念をカバーし、JSONなどのより複雑なデータ形式を返すために必要な基盤を提供します。

まず、演習や記事の他の演習を行うために、アクセス可能なコーディング環境をセットアップする必要があります。 ターミナルで、というフォルダを作成します first-servers:

  1. mkdir first-servers

次に、そのフォルダに入ります。

  1. cd first-servers

次に、コードを格納するファイルを作成します。

  1. touch hello.js

テキストエディタでファイルを開きます。 我々は使用するだろう nano ターミナルで利用できるように:

  1. nano hello.js

まず、 http すべてのNode.jsインストールで標準のモジュール。 次の行をに追加します hello.js:

first-servers / hello.js
const http = require("http");

The http モジュールには、サーバーを作成する関数が含まれています。これについては後で説明します。 Node.jsのモジュールについて詳しく知りたい場合は、Node.jsモジュールの作成方法の記事をご覧ください。

次のステップは、サーバーがバインドされるホストとポートの2つの定数を定義することです。

first-servers / hello.js
...
const host = 'localhost';
const port = 8000;

前述のように、Webサーバーはブラウザーや他のクライアントからの要求を受け入れます。 DNSサーバーによってIPアドレスに変換されるドメイン名を入力することにより、Webサーバーと対話する場合があります。 IPアドレスは、インターネットなどのネットワーク上のマシンを識別する一意の一連の番号です。 ドメイン名の概念の詳細については、 DNSの用語、コンポーネント、および概念の概要の記事を参照してください。

localhost コンピュータが自分自身を参照するために使用する特別なプライベートアドレスです。 これは通常、内部IPアドレスに相当します 127.0.0.1 また、ローカルコンピュータでのみ利用でき、参加しているローカルネットワークやインターネットでは利用できません。

ポートは、サーバーがIPアドレスへのエンドポイントまたは「ドア」として使用する番号です。 この例では、ポートを使用します 8000 私たちのウェブサーバーのために。 ポート 80808000 通常、開発ではデフォルトのポートとして使用され、ほとんどの場合、開発者はHTTPサーバーの他のポートではなくそれらを使用します。

サーバーをこのホストとポートにバインドすると、次のサイトにアクセスしてサーバーにアクセスできるようになります。 http://localhost:8000 ローカルブラウザで。

Node.jsでリクエストリスナーと呼ぶ特別な関数を追加しましょう。 この関数は、着信HTTP要求を処理し、HTTP応答を返すことを目的としています。 この関数には、要求オブジェクトと応答オブジェクトの2つの引数が必要です。 リクエストオブジェクトは、着信するHTTPリクエストのすべてのデータをキャプチャします。 応答オブジェクトは、サーバーのHTTP応答を返すために使用されます。

誰かがアクセスするたびに、最初のサーバーがこのメッセージを返すようにします。 "My first server!".

次にその関数を追加しましょう:

first-servers / hello.js
...

const requestListener = function (req, res) {
    res.writeHead(200);
    res.end("My first server!");
};

関数は通常、その機能に基づいて名前が付けられます。 たとえば、本のリストを返すリクエストリスナー関数を作成した場合、名前を付ける可能性があります。 listBooks(). これはサンプルケースなので、一般的な名前を使用します requestListener.

Node.jsのすべてのリクエストリスナー関数は、次の2つの引数を受け入れます。 reqres (必要に応じて、別の名前を付けることができます)。 ユーザーが送信するHTTPリクエストは、最初の引数に対応するRequestオブジェクトにキャプチャされます。 req. ユーザーに返すHTTP応答は、2番目の引数でResponseオブジェクトと対話することによって形成されます。 res.

最初の行 res.writeHead(200); 応答のHTTPステータスコードを設定します。 HTTPステータスコードは、HTTPリクエストがサーバーによってどの程度適切に処理されたかを示します。 この場合、ステータスコード 200 に対応 "OK". Webサーバーが意味する意味で返すことができるさまざまなHTTPコードについて知りたい場合は、一般的なHTTPエラーコードのトラブルシューティング方法に関するガイドから始めることをお勧めします。

関数の次の行、 res.end("My first server!");、HTTP応答を要求したクライアントに書き戻します。 この関数は、サーバーが返さなければならないすべてのデータを返します。 この場合、テキストデータを返します。

最後に、サーバーを作成してリクエストリスナーを利用できるようになりました。

first-servers / hello.js
...

const server = http.createServer(requestListener);
server.listen(port, host, () => {
    console.log(`Server is running on http://${host}:${port}`);
});

保存して終了 nano を押すことによって CTRL+X.

最初の行で、新しいを作成します server 経由のオブジェクト http モジュールの createServer() 関数。 このサーバーはHTTPリクエストを受け入れ、それらを requestListener() 関数。

サーバーを作成したら、それをネットワークアドレスにバインドする必要があります。 私たちはそれを server.listen() 方法。 次の3つの引数を受け入れます。 port, host、およびサーバーがリッスンを開始したときに起動するコールバック関数

これらの引数はすべてオプションですが、Webサーバーで使用するポートとホストを明示的に指定することをお勧めします。 Webサーバーをさまざまな環境に展開する場合、負荷分散または DNS エイリアスを設定するには、Webサーバーが実行されているポートとホストを知っている必要があります。

コールバック関数はコンソールにメッセージを記録するので、サーバーがいつ接続をリッスンし始めたかを知ることができます。

注: requestListener() を使用しません req オブジェクトの場合でも、関数の最初の引数である必要があります。

15行未満のコードで、Webサーバーができました。 実際の動作を確認し、プログラムを実行してエンドツーエンドでテストしてみましょう。

  1. node hello.js

コンソールに、次の出力が表示されます。

Output
Server is running on http://localhost:8000

プロンプトが消えることに注意してください。 これは、Node.jsサーバーが長時間実行されるプロセスであるためです。 クラッシュして終了するエラーが発生した場合、またはサーバーの実行中のNode.jsプロセスを停止した場合にのみ終了します。

別のターミナルウィンドウで、ネットワークとの間でデータを転送するためのCLIツールであるcURLを使用してサーバーと通信します。 コマンドを入力してHTTPを作成します GET 実行中のサーバーへのリクエスト:

  1. curl http://localhost:8000

押すと ENTER、端末には次の出力が表示されます。

Output
My first server!

これでサーバーがセットアップされ、最初のサーバー応答が得られました。

サーバーをテストしたときに何が起こったのかを分析してみましょう。 cURLを使用して、 GET サーバーへのリクエスト http://localhost:8000. Node.jsサーバーは、そのアドレスからの接続をリッスンしました。 サーバーはそのリクエストを requestListener() 関数。 この関数は、ステータスコードを含むテキストデータを返しました 200. 次に、サーバーはその応答をcURLに送り返し、cURLは端末にメッセージを表示しました。

続行する前に、を押して実行中のサーバーを終了しましょう CTRL+C. これにより、サーバーの実行が中断され、コマンドラインプロンプトに戻ります。

アクセスするほとんどのWebサイトまたは使用するAPIでは、サーバーの応答がプレーンテキストで表示されることはめったにありません。 一般的な応答形式としてHTMLページとJSONデータを取得します。 次のステップでは、Webで遭遇する一般的なデータ形式でHTTP応答を返す方法を学習します。

ステップ2—さまざまな種類のコンテンツを返す

Webサーバーから返される応答は、さまざまな形式をとることができます。 JSONとHTMLについては前に説明しましたが、XMLやCSVなどの他のテキスト形式を返すこともできます。 最後に、Webサーバーは、PDF、zipファイル、オーディオ、ビデオなどの非テキストデータを返すことができます。

この記事では、返されたプレーンテキストに加えて、次の種類のデータを返す方法を学習します。

3つのデータ型はすべてテキストベースであり、Web上でコンテンツを配信するための一般的な形式です。 多くのサーバー側の開発言語とツールは、これらのさまざまなデータ型を返すことをサポートしています。 Node.jsのコンテキストでは、次の2つのことを行う必要があります。

  1. をセットする Content-Type 適切な値を持つHTTP応答のヘッダー。
  2. 確認しておいて res.end() 正しい形式でデータを取得します。

いくつかの例を使って、これを実際に見てみましょう。 このセクションで作成するコードとそれ以降のコードは、以前に作成したコードと多くの類似点があります。 ほとんどの変更は、 requestListener() 関数。 この「テンプレートコード」を使用してファイルを作成し、今後のセクションをわかりやすくします。

と呼ばれる新しいファイルを作成します html.js. このファイルは、後でHTTP応答でHTMLテキストを返すために使用されます。 ここにテンプレートコードを配置し、さまざまなタイプを返す他のサーバーにコピーします。

ターミナルで、次のように入力します。

  1. touch html.js

次に、このファイルをテキストエディタで開きます。

  1. nano html.js

「テンプレートコード」をコピーしてみましょう。 これを入力してください nano:

first-servers / html.js
const http = require("http");

const host = 'localhost';
const port = 8000;

const requestListener = function (req, res) {};

const server = http.createServer(requestListener);
server.listen(port, host, () => {
    console.log(`Server is running on http://${host}:${port}`);
});

保存して終了 html.jsCTRL+X、ターミナルに戻ります。

次に、このファイルを2つの新しいファイルにコピーしましょう。 最初のファイルは、HTTP応答でCSVデータを返すことです。

  1. cp html.js csv.js

2番目のファイルは、サーバーでJSON応答を返します。

  1. cp html.js json.js

残りのファイルは、後の演習用になります。

  1. cp html.js htmlFile.js
  2. cp html.js routes.js

これで、演習を続行する準備が整いました。 JSONを返すことから始めましょう。

JSONの提供

JavaScript Object Notation は、一般にJSONと呼ばれ、テキストベースのデータ交換形式です。 その名前が示すように、JavaScriptオブジェクトから派生していますが、言語に依存しないため、構文を解析できるすべてのプログラミング言語で使用できます。

JSONは、データを受け入れて返すためにAPIによって一般的に使用されます。 その人気は、XMLなどの以前のデータ交換標準よりもデータ転送サイズが小さいことと、プログラムが過度の労力をかけずにそれらを解析できるようにするツールが存在することによるものです。 JSONについて詳しく知りたい場合は、JavaScriptでJSONを操作する方法に関するガイドをご覧ください。

を開きます json.js とファイル nano:

  1. nano json.js

JSON応答を返したい。 変更してみましょう requestListener() 次のように強調表示された行を変更することにより、すべてのJSON応答が持つ適切なヘッダーを返す関数。

first-servers / json.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
};
...

The res.setHeader() メソッドは、応答にHTTPヘッダーを追加します。 HTTPヘッダーは、リクエストまたはレスポンスに添付できる追加情報です。 The res.setHeader() メソッドは、ヘッダーの名前とその値の2つの引数を取ります。

The Content-Type ヘッダーは、要求または応答とともに送信されるデータの形式(メディアタイプとも呼ばれます)を示すために使用されます。 この場合、 Content-Typeapplication/json.

それでは、JSONコンテンツをユーザーに返しましょう。 変更 json.js したがって、次のようになります。

first-servers / json.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    res.writeHead(200);
    res.end(`{"message": "This is a JSON response"}`);
};
...

以前と同様に、次のステータスコードを返すことで、リクエストが成功したことをユーザーに通知します。 200. 今回は response.end() 呼び出し、文字列引数に有効なJSONが含まれています。

保存して終了 json.js を押すことによって CTRL+X. それでは、サーバーを実行してみましょう。 node 指図:

  1. node json.js

別の端末で、cURLを使用してサーバーにアクセスしましょう。

  1. curl http://localhost:8000

押すと ENTER、次の結果が表示されます。

Output
{"message": "This is a JSON response"}

これで、アプリを作成する一般的なAPIの多くと同様に、JSON応答が正常に返されました。 実行中のサーバーを必ず終了してください CTRL+C これで、標準のターミナルプロンプトに戻ることができます。 次に、データを返すもう1つの一般的な形式であるCSVを見てみましょう。

CSVを提供

カンマ区切り値(CSV)ファイル形式は、表形式のデータを提供するために一般的に使用されるテキスト標準です。 ほとんどの場合、各行は改行で区切られ、行の各項目はコンマで区切られます。

ワークスペースで、 csv.js テキストエディタでファイル:

  1. nano csv.js

次の行を追加してみましょう requestListener() 関数:

first-servers / csv.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "text/csv");
    res.setHeader("Content-Disposition", "attachment;filename=oceanpals.csv");
};
...

今回は Content-Type CSVファイルが値として返されることを示します text/csv. 追加する2番目のヘッダーは Content-Disposition. このヘッダーは、特にブラウザーで、または別のファイルとしてデータを表示する方法をブラウザーに指示します。

CSV応答を返すと、最新のブラウザのほとんどは、 Content-Disposition ヘッダーが設定されていません。 ただし、CSVファイルを返す場合は、CSVファイルの名前を設定できるため、このヘッダーを追加する必要があります。 この場合、このCSVファイルは添付ファイルであり、ダウンロードする必要があることをブラウザに通知します。 次に、ファイルの名前が oceanpals.csv.

HTTP応答にCSVデータを書き込みましょう。

first-servers / csv.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "text/csv");
    res.setHeader("Content-Disposition", "attachment;filename=oceanpals.csv");
    res.writeHead(200);
    res.end(`id,name,email\n1,Sammy Shark,shark@ocean.com`);
};
...

前のように 200/OK 私たちの応答でステータス。 今回は、 res.end() 有効なCSVである文字列があります。 カンマは、各列の値と改行文字(\n)行を区切ります。 2つの行があります。1つはテーブルヘッダー用で、もう1つはデータ用です。

このサーバーをブラウザーでテストします。 保存 csv.js でエディタを終了します CTRL+X.

Node.jsコマンドを使用してサーバーを実行します。

  1. node csv.js

別のターミナルで、cURLを使用してサーバーにアクセスしましょう。

  1. curl http://localhost:8000

コンソールには次のように表示されます。

Output
id,name,email 1,Sammy Shark,shark@ocean.com

に行くなら http://localhost:8000 ブラウザでは、CSVファイルがダウンロードされます。 そのファイル名は oceanpals.csv.

実行中のサーバーを終了します CTRL+C 標準のターミナルプロンプトに戻ります。

JSONとCSVを返したので、APIで人気のある2つのケースについて説明しました。 人々がブラウザで表示するWebサイトのデータを返す方法に移りましょう。

HTMLの提供

HTML、ハイパーテキストマークアップ言語は、ユーザーがWebブラウザーを介してサーバーと対話する場合に使用する最も一般的な形式です。 これは、Webコンテンツを構造化するために作成されました。 Webブラウザーは、HTMLコンテンツ、および CSS で追加したスタイルを表示するように構築されています。これは、Webサイトの美しさを変えることができるもう1つのフロントエンドWebテクノロジーです。

再開しましょう html.js 私たちのテキストエディタで:

  1. nano html.js

を変更します requestListener() 適切なを返す関数 Content-Type HTML応答のヘッダー:

first-servers / html.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "text/html");
};
...

それでは、HTMLコンテンツをユーザーに返しましょう。 強調表示された行をに追加します html.js したがって、次のようになります。

first-servers / html.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "text/html");
    res.writeHead(200);
    res.end(`<html><body><h1>This is HTML</h1></body></html>`);
};
...

まず、HTTPステータスコードを追加します。 次に、 response.end() 有効なHTMLを含む文字列引数を使用します。 ブラウザでサーバーにアクセスすると、1つのヘッダータグを含むHTMLページが表示されます。 This is HTML.

を押して保存して終了しましょう CTRL+X. それでは、サーバーを実行してみましょう。 node 指図:

  1. node html.js

様子を見よう Server is running on http://localhost:8000 私たちのプログラムが始まったとき。

次に、ブラウザにアクセスして、 http://localhost:8000. 私たちのページは次のようになります。

実行中のサーバーを終了しましょう CTRL+C そして、標準のターミナルプロンプトに戻ります。

Node.jsプログラムのように、サーバー側のコードとは別に、HTMLをファイルに書き込むのが一般的です。 次に、ファイルからHTML応答を返す方法を見てみましょう。

ステップ3—ファイルからHTMLページを提供する

Node.jsでHTMLを文字列としてユーザーに提供できますが、HTMLファイルをロードしてそのコンテンツを提供することをお勧めします。 このように、HTMLファイルが大きくなるにつれて、Node.jsコードで長い文字列を維持する必要がなくなり、より簡潔になり、Webサイトの各側面で独立して作業できるようになります。 この「関心の分離」は多くのWeb開発セットアップで一般的であるため、Node.jsでサポートするためにHTMLファイルをロードする方法を知っておくとよいでしょう。

HTMLファイルを提供するために、 fsモジュールを使用してHTMLファイルをロードし、HTTP応答を書き込むときにそのデータを使用します。

まず、Webサーバーが返すHTMLファイルを作成します。 新しいHTMLファイルを作成します。

  1. touch index.html

開催中 index.html テキストエディタの場合:

  1. nano index.html

私たちのウェブページは最小限になります。 背景はオレンジ色で、中央に挨拶のテキストが表示されます。 次のコードをファイルに追加します。

first-servers / index.html
<!DOCTYPE html>

<head>
    <title>My Website</title>
    <style>
        *,
        html {
            margin: 0;
            padding: 0;
            border: 0;
        }

        html {
            width: 100%;
            height: 100%;
        }

        body {
            width: 100%;
            height: 100%;
            position: relative;
            background-color: rgb(236, 152, 42);
        }

        .center {
            width: 100%;
            height: 50%;
            margin: 0;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            font-family: "Trebuchet MS", Helvetica, sans-serif;
            text-align: center;
        }

        h1 {
            font-size: 144px;
        }

        p {
            font-size: 64px;
        }
    </style>
</head>

<body>
    <div class="center">
        <h1>Hello Again!</h1>
        <p>This is served from a file</p>
    </div>
</body>

</html>

この1つのWebページには、2行のテキストが表示されます。 Hello Again!This is served from a file. 線はページの中央に上下に表示されます。 テキストの最初の行は見出しに表示されます。これは、テキストが大きくなることを意味します。 テキストの2行目は少し小さく表示されます。 すべてのテキストは白で表示され、Webページの背景はオレンジ色になります。

この記事やシリーズの範囲ではありませんが、HTML、CSS、およびその他のフロントエンドWebテクノロジーについて詳しく知りたい場合は、MozillaのWeb入門ガイドを参照してください。 。

HTMLに必要なのはこれだけなので、ファイルを保存して終了します。 CTRL+X. これで、サーバーコードに進むことができます。

この演習では、次の作業を行います htmlFile.js. テキストエディタで開きます。

  1. nano htmlFile.js

ファイルを読み取る必要があるため、まずインポートします。 fs モジュール:

first-servers / htmlFile.js
const http = require("http");
const fs = require('fs').promises;
...

このモジュールには、 readFile() HTMLファイルを所定の位置にロードするために使用する関数。 最新のJavaScriptのベストプラクティスに従って、promiseバリアントをインポートします。 コールバックよりも構文的に簡潔なpromiseを使用します。これは、割り当てた場合に使用する必要があります。 fs ただ require('fs'). 非同期プログラミングのベストプラクティスの詳細については、Node.jsガイドで非同期コードを作成する方法をご覧ください。

ユーザーがシステムを要求したときにHTMLファイルが読み取られるようにします。 変更することから始めましょう requestListener() ファイルを読み取るには:

first-servers / htmlFile.js
...
const requestListener = function (req, res) {
    fs.readFile(__dirname + "/index.html")
};
...

を使用します fs.readFile() ファイルをロードするメソッド。 その議論は __dirname + "/index.html". 特別な変数__dirname には、Node.jsコードが実行されている場所の絶対パスがあります。 次に追加します /index.html これで、前に作成したHTMLファイルをロードできます。

次に、ロードされたHTMLページを返します。

first-servers / htmlFile.js
...
const requestListener = function (req, res) {
    fs.readFile(__dirname + "/index.html")
        .then(contents => {
            res.setHeader("Content-Type", "text/html");
            res.writeHead(200);
            res.end(contents);
        })
};
...

の場合 fs.readFile() promiseは正常に解決され、データを返します。 を使用します then() この場合を処理する方法。 The contents パラメータには、HTMLファイルのデータが含まれています。

最初に設定します Content-Type ヘッダー text/html HTMLデータを返すことをクライアントに通知します。 次に、リクエストが成功したことを示すステータスコードを記述します。 最後に、ロードしたHTMLページをクライアントに送信します。 contents 変数。

The fs.readFile() メソッドが失敗することがあるため、エラーが発生したときにこのケースを処理する必要があります。 これをに追加します requestListener() 関数:

first-servers / htmlFile.js
...
const requestListener = function (req, res) {
    fs.readFile(__dirname + "/index.html")
        .then(contents => {
            res.setHeader("Content-Type", "text/html");
            res.writeHead(200);
            res.end(contents);
        })
        .catch(err => {
            res.writeHead(500);
            res.end(err);
            return;
        });
};
...

ファイルを保存して終了します nanoCTRL+X.

promiseでエラーが発生すると、それは拒否されます。 その場合は、 catch() 方法。 それは次のエラーを受け入れます fs.readFile() 戻り、ステータスコードをに設定します 500 内部エラーが発生したことを示し、エラーをユーザーに返します。

サーバーを実行します node 指図:

  1. node htmlFile.js

Webブラウザーで、次のWebサイトにアクセスします。 http://localhost:8000. このページが表示されます:

これで、サーバーからユーザーにHTMLページが返されました。 実行中のサーバーを終了できます CTRL+C. 実行すると、ターミナルプロンプトが返されます。

本番環境でこのようなコードを作成する場合、HTTPリクエストを受け取るたびにHTMLページをロードしたくない場合があります。 このHTMLページのサイズは約800バイトですが、より複雑なWebサイトのサイズはメガバイトになる可能性があります。 大きなファイルの読み込みには時間がかかる場合があります。 サイトで大量のトラフィックが予想される場合は、起動時にHTMLファイルをロードし、その内容を保存するのが最適な場合があります。 それらがロードされた後、サーバーをセットアップして、アドレス上の要求をリッスンさせることができます。

この方法を示すために、サーバーをより効率的でスケーラブルに作り直す方法を見てみましょう。

HTMLを効率的に提供する

すべてのリクエストに対してHTMLをロードする代わりに、このステップでは最初に1回ロードします。 リクエストは、起動時にロードしたデータを返します。

ターミナルで、テキストエディタを使用してNode.jsスクリプトを再度開きます。

  1. nano htmlFile.js

作成する前に、新しい変数を追加することから始めましょう。 requestListener() 関数:

first-servers / htmlFile.js
...
let indexFile;

const requestListener = function (req, res) {
...

このプログラムを実行すると、この変数はHTMLファイルの内容を保持します。

それでは、再調整しましょう requestListener() 関数。 ファイルをロードする代わりに、次の内容を返すようになりました。 indexFile:

first-servers / htmlFile.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "text/html");
    res.writeHead(200);
    res.end(indexFile);
};
...

次に、ファイル読み取りロジックを requestListener() サーバーの起動に機能します。 サーバーを作成するときに、次の変更を加えます。

first-servers / htmlFile.js
...

const server = http.createServer(requestListener);

fs.readFile(__dirname + "/index.html")
    .then(contents => {
        indexFile = contents;
        server.listen(port, host, () => {
            console.log(`Server is running on http://${host}:${port}`);
        });
    })
    .catch(err => {
        console.error(`Could not read index.html file: ${err}`);
        process.exit(1);
    });

ファイルを保存して終了します nanoCTRL+X.

ファイルを読み取るコードは、最初の試行で記述したものと似ています。 ただし、ファイルの読み取りに成功すると、コンテンツがグローバルに保存されます。 indexFile 変数。 次に、サーバーを起動します。 listen() 方法。 重要なのは、サーバーが実行される前にファイルがロードされることです。 このように、 requestListener() 関数は必ずHTMLページを返します。 indexFile 空の変数ではなくなりました。

エラーハンドラも変更されました。 ファイルを読み込めない場合は、エラーをキャプチャしてコンソールに出力します。 次に、Node.jsプログラムを終了します。 exit() サーバーを起動せずに機能します。 このようにして、ファイルの読み取りが失敗した理由を確認し、問題に対処してから、サーバーを再起動します。

これで、さまざまなタイプのデータをユーザーに返すさまざまなWebサーバーが作成されました。 これまでのところ、何を返すかを決定するためにリクエストデータを使用していません。 Node.jsサーバーでさまざまなルートまたはパスを設定するときにリクエストデータを使用する必要があるため、次に、それらがどのように連携するかを見てみましょう。

ステップ4—HTTPリクエストオブジェクトを使用したルートの管理

アクセスするほとんどのWebサイトまたは使用するAPIには通常、複数のエンドポイントがあるため、さまざまなリソースにアクセスできます。 良い例は、図書館で使用される可能性のある本の管理システムです。 書籍データを管理するだけでなく、目録作成や検索に便利な著者データも管理する必要があります。

本と著者のデータは関連していますが、それらは2つの異なるオブジェクトです。 このような場合、ソフトウェア開発者は通常、APIユーザーに操作しているデータの種類を示す方法として、さまざまなエンドポイントで各オブジェクトをコーディングします。

2つの異なるタイプのデータを返す小さなライブラリ用の新しいサーバーを作成しましょう。 ユーザーが次のサーバーのアドレスにアクセスした場合 /books、JSONで本のリストを受け取ります。 彼らが行くなら /authors、JSONで著者情報のリストを受け取ります。

これまでのところ、受け取ったすべてのリクエストに対して同じ応答を返してきました。 これを簡単に説明しましょう。

JSON応答の例を再実行します。

  1. node json.js

別の端末で、前のようにcURLリクエストを実行しましょう。

  1. curl http://localhost:8000

次のように表示されます。

Output
{"message": "This is a JSON response"}

次に、別のcurlコマンドを試してみましょう。

  1. curl http://localhost:8000/todos

押した後 Enter、同じ結果が表示されます。

Output
{"message": "This is a JSON response"}

特別なロジックは構築していません requestListener() URLに含まれるリクエストを処理する関数 /todosしたがって、Node.jsはデフォルトで同じJSONメッセージを返します。

ミニチュアライブラリ管理サーバーを構築したいので、ユーザーがアクセスするエンドポイントに基づいて、返されるデータの種類を分離します。

まず、実行中のサーバーを終了します CTRL+C.

開催中 routes.js テキストエディタで:

  1. nano routes.js

まず、JSONデータを変数に格納してから requestListener() 関数:

first-servers / routers.js
...
const books = JSON.stringify([
    { title: "The Alchemist", author: "Paulo Coelho", year: 1988 },
    { title: "The Prophet", author: "Kahlil Gibran", year: 1923 }
]);

const authors = JSON.stringify([
    { name: "Paulo Coelho", countryOfBirth: "Brazil", yearOfBirth: 1947 },
    { name: "Kahlil Gibran", countryOfBirth: "Lebanon", yearOfBirth: 1883 }
]);
...

The books variableは、ブックオブジェクトの配列のJSONを含む文字列です。 各本には、タイトルまたは名前、著者、および出版された年があります。

The authors variableは、作成者オブジェクトの配列のJSONを含む文字列です。 各著者には、名前、出生国、および出生年があります。

応答が返すデータが得られたので、次の変更を開始しましょう。 requestListener() それらを正しいルートに戻す関数。

まず、サーバーからのすべての応答が正しいことを確認します Content-Type ヘッダ:

first-servers / routers.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
}
...

ここで、ユーザーがアクセスするURLパスに応じて適切なJSONを返します。 リクエストのURLにswitchステートメントを作成しましょう。

first-servers / routers.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    switch (req.url) {}
}
...

リクエストオブジェクトからURLパスを取得するには、そのオブジェクトにアクセスする必要があります url 財産。 ケースを追加できるようになりました switch 適切なJSONを返すステートメント。

JavaScriptの switch ステートメントは、オブジェクトまたはJavaScript式の値(たとえば、数学演算の結果)に応じて実行されるコードを制御する方法を提供します。 それらの使用方法に関するレッスンやリマインダーが必要な場合は、JavaScriptでSwitchステートメントを使用する方法に関するガイドをご覧ください。

続けて、 case ユーザーが書籍のリストを取得したい場合:

first-servers / routers.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    switch (req.url) {
        case "/books":
            res.writeHead(200);
            res.end(books);
            break
    }
}
...

ステータスコードをに設定します 200 リクエストが正常であることを示し、書籍のリストを含むJSONを返します。 今度は別のものを追加しましょう case 私たちの著者のために:

first-servers / routers.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    switch (req.url) {
        case "/books":
            res.writeHead(200);
            res.end(books);
            break
        case "/authors":
            res.writeHead(200);
            res.end(authors);
            break
    }
}
...

以前と同様に、ステータスコードは次のようになります 200 リクエストは大丈夫です。 今回は、作成者のリストを含むJSONを返します。

ユーザーが他のパスに移動しようとすると、エラーを返します。 これを行うためにデフォルトのケースを追加しましょう:

ルート.js
...
const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    switch (req.url) {
        case "/books":
            res.writeHead(200);
            res.end(books);
            break
        case "/authors":
            res.writeHead(200);
            res.end(authors);
            break
        default:
            res.writeHead(404);
            res.end(JSON.stringify({error:"Resource not found"}));
    }
}
...

を使用します default のキーワード switch 以前のケースではキャプチャされなかった他のすべてのシナリオをキャプチャするステートメント。 ステータスコードをに設定します 404 探していたURLが見つからなかったことを示します。 次に、エラーメッセージを含むJSONオブジェクトを設定します。

サーバーをテストして、期待どおりに動作するかどうかを確認しましょう。 別の端末で、最初にコマンドを実行して、本のリストが返されるかどうかを確認しましょう。

  1. curl http://localhost:8000/books

プレス Enter 次の出力を表示するには:

Output
[{"title":"The Alchemist","author":"Paulo Coelho","year":1988},{"title":"The Prophet","author":"Kahlil Gibran","year":1923}]

ここまでは順調ですね。 同じことを試してみましょう /authors. ターミナルで次のコマンドを入力します。

  1. curl http://localhost:8000/authors

コマンドが完了すると、次の出力が表示されます。

Output
[{"name":"Paulo Coelho","countryOfBirth":"Brazil","yearOfBirth":1947},{"name":"Kahlil Gibran","countryOfBirth":"Lebanon","yearOfBirth":1883}]

最後に、間違ったURLを試して、次のことを確認しましょう。 requestListener() エラー応答を返します:

  1. curl http://localhost:8000/notreal

そのコマンドを入力すると、次のメッセージが表示されます。

Output
{"error":"Resource not found"}

実行中のサーバーを終了するには、 CTRL+C.

これで、ユーザーがさまざまなデータを取得するためのさまざまな手段が作成されました。 また、サポートされていないURLをユーザーが入力した場合にHTTPエラーを返すデフォルトの応答を追加しました。

結論

このチュートリアルでは、一連のNode.jsHTTPサーバーを作成しました。 最初に、基本的なテキスト応答を返しました。 次に、サーバーからさまざまな種類のデータ(JSON、CSV、HTML)を返しました。 そこから、ファイルの読み込みとHTTP応答を組み合わせて、サーバーからユーザーにHTMLページを返し、ユーザーの要求に関する情報を使用して応答で送信するデータを決定するAPIを作成することができました。

これで、さまざまな要求と応答を処理できるWebサーバーを作成する準備が整いました。 この知識があれば、さまざまなエンドポイントのユーザーに多くのHTMLページを返すサーバーを作成できます。 独自のAPIを作成することもできます。

Node.jsのその他のHTTPWebサーバーについては、Node.jsのドキュメントをご覧ください。 http モジュール。 Node.jsの学習を続けたい場合は、Node.jsシリーズのコーディング方法ページに戻ることができます。

モバイルバージョンを終了