1、分析を開始します
まず、「HTTP」の概念をよく知っておく必要があります。これは、特定の言語に基づいたものではありませんが、実装の詳細は異なります。
という考えも同じです。
NodeJS は、ホスト言語として JavaScript を使用します。この記事では、「Http モジュール」についても説明します。ただし前提として、
まず公式 Web サイトが提供する API を読んで事前に理解しておくと、より便利になります。以下は、HTTP 部分の API の概要です。
HTTP
http.STATUS_CODES
http.createServer([requestListener])
http.createClient([ポート], [ホスト])
クラス: http.Server
イベント: 'リクエスト'
イベント: '接続'
イベント: 「閉じる」
イベント: 'checkContinue'
イベント: 「接続」
イベント: 'アップグレード'
イベント: 'clientError'
server.listen(ポート, [ホスト名], [バックログ], [コールバック])
server.listen(パス, [コールバック])
server.listen(ハンドル, [コールバック])
server.close([コールバック])
server.maxHeadersCount
server.setTimeout(ミリ秒, コールバック)
サーバー.タイムアウト
クラス: http.ServerResponse
イベント: 「閉じる」
response.writeContinue()
response.writeHead(statusCode, [reasonPhrase], [headers])
response.setTimeout(ミリ秒, コールバック)
応答.ステータスコード
response.setHeader(名前, 値)
response.headersSent
応答.sendDate
response.getHeader(名前)
response.removeHeader(名前)
response.write(チャンク, [エンコーディング])
response.addTrailers(headers)
response.end([データ], [エンコーディング])
http.request(オプション、コールバック)
http.get(オプション, コールバック)
クラス: http.Agent
新しいエージェント([オプション])
Agent.maxSockets
Agent.maxFreeSockets
エージェント.ソケット
Agent.freeSockets
エージェント.リクエスト
エージェント.destroy()
Agent.getName(オプション)
http.globalAgent
クラス: http.ClientRequest
イベント「応答」
イベント: 'ソケット'
イベント: 「接続」
イベント: 'アップグレード'
イベント: 「継続」
request.write(チャンク, [エンコーディング])
request.end([データ], [エンコーディング])
request.abort()
request.setTimeout(タイムアウト, [コールバック])
request.setNoDelay([noDelay])
request.setSocketKeepAlive([enable], [initialDelay])
http.IncomingMessage
イベント: 「閉じる」
message.httpVersion
message.headers
message.rawHeaders
メッセージ.トレーラー
message.rawTrailers
message.setTimeout(ミリ秒, コールバック)
メッセージ.メソッド
メッセージ.url
message.statusCode
メッセージ.ソケット
让我们先一简单例開始,创建一叫server.jsの文件,并写入下代:
var http = require('http') ;
var サーバー = http.createServer(function(req,res){
res.writeHeader(200,{
'Content-Type' : 'text/plain;charset=utf-8' // charset=utf-8 を追加
}) ;
res.end("こんにちは、ビッグベア!") ;
}) ;
サーバー.listen(8888) ;
console.log("http サーバーはポート 8888 で実行されています ...") ;
(nodeserver.js) 結果は次のとおりです:
2. 詳細な分析例
この小さな例を詳しく見てみましょう:
(1行目): NodeJSに付属する「http」モジュールを「require」で導入し、http変数に割り当てます。
(2行): httpモジュールが提供する関数「createServer」を呼び出します。この関数は、新しい Web サーバー オブジェクトを返します。
パラメータ「requestListener」は、「リクエスト」イベントのリスニングキューに自動的に追加される関数です。
リクエストが来ると、Event-Loop はリスナーのコールバック関数を実行キューに入れ、ノード内のすべてのコードが実行キューから 1 つずつ取り出されて実行されます。
これらの実行はすべて作業スレッド上で実行されます (イベント ループ自体は独立したスレッド内にあると考えることができます。通常、このスレッドについては言及しませんが、ノードをシングルスレッド実行環境と呼びます)、
すべてのコールバックはワーカー スレッドで実行されます。
コールバック関数「requestListener」をもう一度見てみましょう。この関数は 2 つのパラメータ (リクエスト、レスポンス) を提供します。
リクエストが受信されるたびに起動されます。各接続には複数のリクエストが含まれる可能性があることに注意してください (キープアライブ接続の場合)。
"request" は http.IncomingMessage のインスタンスです。 「response」は http.ServerResponse のインスタンスです。
http リクエスト オブジェクトは読み取り可能なストリームであり、http 応答オブジェクトは書き込み可能なストリームです。
"IncomingMessage" オブジェクトは http.Server または http.ClientRequest によって作成されます。
そして、最初のパラメータとしてそれぞれ「リクエスト」イベントと「レスポンス」イベントに渡されます。
応答ステータス、ヘッダー、データへのアクセスにも使用できます。
「Stream」インターフェースと以下の追加のイベント、メソッド、プロパティを実装します。 (詳細については API を参照してください)。
(3 行): "writeHeader"、"response.writeHead()" 関数を使用して、HTTP ステータス 200 と Http ヘッダーのコンテンツ タイプを送信します。
リクエストに応答ヘッダーを返信します。 「statusCode」は、404 などの 3 桁の HTTP ステータス コードです。最後のパラメータ「headers」は、応答ヘッダーの内容です。
例を挙げてみましょう:
var body = 'hello world' ;
response.writeHead(200, {
「コンテンツの長さ」: body.length,
'Content-Type': 'text/plain'
}) ;
注: Content-Length は文字数ではなくバイト数で計算されます。
前の例の理由は、文字列「Hello World!」には半角文字しか含まれていないためです。
本文にマルチバイトエンコードされた文字が含まれている場合は、Buffer.byteLength() を使用して、マルチバイト文字エンコードの場合の文字列のバイト数を決定する必要があります。
ノードは Content-Lenth 属性が送信された本文の長さと一致するかどうかをチェックしないことをさらに説明する必要があります。
statusCode は 3 桁の HTTP ステータス コードです (例: 「404」)。ここで説明したいのは、「http.STATUS_CODES」です。これには、すべての標準「HTTP」応答ステータス コードのコレクションと短い説明が含まれています。
以下はソースコードリファレンスです:
var STATUS_CODES = exports.STATUS_CODES = {
100 : 「続行」、
101 : 'プロトコルの切り替え'、
102 : '処理中', // RFC 2518、RFC 4918 によって廃止されました
200 : 「わかりました」
201 : '作成されました'、
202 : '承認されました'、
203 : '非権威情報'、
204 : 'コンテンツがありません'、
205 : 'コンテンツをリセット'、
206 : '部分的なコンテンツ'、
207 : 'マルチステータス', // RFC 4918
300 : '複数の選択肢'、
301 : '永久に移動されました'、
302 : '一時的に移動しました'、
303 : '他のものを見る'、
304 : '未変更'、
305 : 'プロキシを使用'、
307 : '一時的なリダイレクト'、
400 : 「不正なリクエスト」、
401 : '不正'、
402 : '支払いが必要です'、
403 : '禁止'、
404 : '見つかりません'、
405 : 'メソッドは許可されていません'、
406 : '受け入れられません'、
407 : 'プロキシ認証が必要です'、
408 : 'リクエストタイムアウト'、
409 : '紛争'、
410 : 「消えた」
411 : '長さが必要です'、
412 : '前提条件が失敗しました'、
413 : 'リクエストエンティティが大きすぎます'、
414 : 'リクエスト URI が大きすぎます'、
415 : 'サポートされていないメディア タイプ'、
416 : '要求された範囲は満たされません'、
417 : '期待は外れました'、
418 : '私はティーポットです'、 // RFC 2324
422 : '処理できないエンティティ', // RFC 4918
423 : 'ロックされました', // RFC 4918
424 : 「依存関係の失敗」 // RFC 4918
425 : '順序なしコレクション', // RFC 4918
426 : 'アップグレードが必要です'、 // RFC 2817
500 : '内部サーバー エラー'、
501 : '未実装'、
502 : '不正なゲートウェイ'、
503 : 'サービスは利用できません'、
504 : 'ゲートウェイ タイムアウト'、
505 : 'HTTP バージョンはサポートされていません',
506 : 'バリアントもネゴシエート'、 // RFC 2295
507 : 「ストレージが不十分です」 // RFC 4918
509 : '帯域幅制限を超えました'、
510 : '拡張されていません' // RFC 2774
};
から、Nodejs ソースコード ”http.js” 143 行が開始されます。
其实从客端应答結果も不难看出:
(6 行):"response.end" ---- すべての応答メッセージとテキストの送信が完了すると、このメソッドはメッセージが完了したとみなします。
応答が完了するたびにこのメソッドを使用する必要があります。パラメータ "data" を指定した場合は、最初に "response.write(data, encoding)" を使用した後、再度 "response.end()" を使用することに相当します。
(8行):”server.listen(8888)” ------ サーバー用に指定された句柄が接続され、特定のポートに設定されます。
以上は比較的綿密な分析プロセスであり、コードの数は多くありませんが、今後の高効率な発行 NodeJS アプリケーションを実現するために、いくつかの仕組みを理解するのに役立ちます。
三、实例
「request」オブジェクトを使用して要求データを受信できることに加えて、「request」オブジェクトを単一のデータ ストリームとして要求データを受信することもできます。
これは「POST」要求の例:
复制代码