序文
前回の記事では、サービスの呼び出しや作成・開始方法http
を中心にモジュールの基本的な使い方を紹介しました。特定の HTTP リクエストを処理するには、メソッドに何かを記述します。この記事では、リクエストを処理する 2 つのコア オブジェクトのうちの 1 つを紹介します。createServer
listen
createServer
request
URL
HTTP プロトコルは、最初はネットワーク上で HTML ドキュメントを取得することだけを目的として設計されました。その後の発展に伴い、ネットワーク上のリソースはますます豊富になり、その種類も単一のテキストから画像、音声、ビデオなどのマルチメディアタイプまで発展しました。しかし、それがどのような種類のリソースであっても、インターネット世界全体で一意の識別子、つまりURL (Uniform Resource Locator (Uniform Resource Locator))を持っています。
URL の構成は次のとおりです。
- スキーム : これは私たちがよく「プロトコル」と呼ぶもので、「HTTP 決定版ガイド」では「スキーム」と訳されています。一般的に使用されるプロトコルは、HTTP、FTP、SMTP などです。
- user:password@: このリソースにアクセスするためのユーザーとパスワードを示します。公開 Web リソースには認証は必要ありません。たとえ必要だったとしても、このような使い方は非常に危険です。通常は直接省略されます。
- host:port: リソースが配置されているホスト名とポート番号を示します。HTTP プロトコルのデフォルトのポート番号は 80、HTTPS プロトコルのデフォルトのポート番号は 443 ですが、どちらも省略できます。
- path: ホスト内のリソースの場所を示すパス。
- query: リソースの追加要件を示すクエリ。
- #fragment: リソース内のアンカー ポイントを表すフラグメント識別子。ブラウザはそれによって示される場所にジャンプできます。ただし、この部分はサーバーには送信されません。
リクエストオブジェクト
HTTP プロトコルは要求応答モデルに基づいており、HTTP2 より前は、クライアントが要求を開始し、サーバーが要求を受信し、処理結果をクライアントに応答する必要がありました。
クライアントが HTTP リクエストをサーバーに送信するときは、特定の URL と HTTP メソッドを指定して、何を書きたいか送信したいかをサーバーに伝える必要があります。通常は、URL または HTTP ヘッダー (ヘッダー) に配置できるいくつかの情報も運びます。データをサーバーに送信する場合は、HTTP メッセージ エンティティに配置することもできます。
http
モジュール内のオブジェクトにはこれらのものが含まれておりrequest
、必要に応じて選択的に解析して使用できます。
解析方法
一般的に使用される HTTP メソッドはGet
、Head
、Post
、Put
、Delete
などで、 をrequest.method
使用して直接取得できます。
const server = http.createServer((request, response) => {
const method = request.method;
console.log(method)
response.end('Hello, World');
});
ブラウザはページを更新し、サーバーは次のように出力します。
URLの解析
URL の構成は比較的複雑であり、request.url
完全な URL のみを から取得できます。たとえば、ブラウザ アクセスhttp://localhost:3000/list?page=10
:
const server = http.createServer((request, response) => {
console.log(request.method)
console.log(request.url)
response.end('Hello, World');
});
コンソールには次のように出力されます。
パス path やクエリ パラメータ クエリなどの特定の部分を取得したい場合は、組み込みモジュールを使用できますurl
。
const http = require('http');
const url = require('url');
const server = http.createServer((request, response) => {
const urlObj = url.parse(request.url)
console.log(urlObj)
response.end('Hello, World');
});
parse
元の URL をオブジェクトに解析するメソッド:
クエリの解析
上記の方法により、現在要求されているリソースのパスとクエリ パラメータを取得できます。ただし、クエリ パラメータは依然として文字列であるため、使用するのが不便です。
組み込みモジュールを使用して解析querystring
することも、URLSearchParams
API を使用して解析することも、サードパーティなどのモジュールを使用して解析することもできます。組み込みモジュールを例として取り上げます。qs
querystringify
querystring
const http = require('http');
const url = require('url');
const qs = require('querystring');
const server = http.createServer((request, response) => {
let {
query } = url.parse(request.url)
query = qs.parse(query)
console.log(query)
response.end('Hello, World');
});
クエリ オブジェクトを簡単に取得できるので、クエリ パラメータを読み取るのに便利です。
ヘッダーの解析中
HTTPリクエストのヘッダ情報はrequest.headers
オブジェクトに配置されます。
const server = http.createServer((request, response) => {
console.log(request.headers);
response.end('Hello, World');
});
ブラウザがリクエストを送信すると、サーバーは次のように出力します。
図に示すようにsec-ch-ua
、このようなsec-ch-ua-mobile
先頭に が付いているリクエスト ヘッダーは、コードによる変更が禁止されている HTTP メッセージ ヘッダーを示しており、ユーザー エージェントがそれらに対する完全な制御を保持します。sec-
たとえば、私たちがよく知っているものはUser-Agent
、通常、バックエンドがユーザーのシステムやプラットフォームに基づいて判断しますが、偽装のために簡単に改変されるため、安全ではありません。ユーザー エージェント情報は、を介してsec-ch-ua
サーバーに安全に渡すことができます。
これらの安全なヘッダーを除いて、残りのヘッダーについてはよく知っています。
-
host: ホスト名へのリクエスト。仮想ホストの設定に使用されます。
-
connection: ネットワーク接続の切断を制御します。HTTP/1.1 のデフォルトは です
keep-alive
。これは接続が長いことを意味します -
キャッシュ制御: 強力なキャッシュを設定します。
-
accept: クライアントが受信できるコンテンツのタイプ。
-
accept-encoding: クライアントが利用できるコンテンツのエンコーディング - 通常はある種の圧縮アルゴリズム。
特定のヘッダーに関する情報を取得するには、角かっこ構文を使用できます。
const server = http.createServer((request, response) => {
console.log(request.headers['content-type']);
response.end('Hello, World');
});
リクエストボディの解析
HTTP メッセージは、リクエスト メッセージとレスポンス メッセージに分けられます。メッセージは次の 3 つの部分で構成されます。
- スタート行:リクエスト行とステータス行に分かれます。
- ヘッダー: リクエストに関する情報を記述し、エンティティデータの情報も記述します。
- エンティティ: 伝送されるデータ。
ファイルのアップロードやフォームの送信などの一部のリクエストでは、メッセージのエンティティで送信されるデータを運ぶ必要があります。
HTTP リクエストは、データの種類に関係なく、データを送信するだけです。したがって、リクエストヘッダーを渡して、Content-Type
このリクエストで運ばれるデータの形式をサーバーに伝えます。request
オブジェクトは受け取ったデータを のエンティティに格納しますrequst.body
。これら 2 つの点に基づいて、クライアントによって送信されたデータを解析できます。
また、request
オブジェクトは読み取り可能なストリームであり、data
イベントをリッスンすることでエンティティ内で送信されたデータを読み取ることができます。イベントが監視されている場合はend
、エンティティ内のデータが読み取られ、解析できることを意味します。
const http = require('http');
const url = require('url');
const server = http.createServer((request, response) => {
const method = request.method;
const {
pathname } = url.parse(request.url);
// 处理 Post /user/login
if(method === 'POST' && pathname === '/user/login') {
let arr = [];
const contentType = request.headers['content-type']
if (contentType === 'application/json') {
// 监听 data 事件,读取实体数据
request.on('data', (data) => {
console.log(data)
arr.push(data)
})
// 监听 end 事件,处理数据
request.on('end', () => {
console.log('传输完毕')
let json = JSON.parse(Buffer.concat(arr).toString())
console.log(json)
})
// 结束响应
response.end('Hello, World');
}
}
});
server.listen(3000, () => {
console.log('服务器启动成功:http://localhost:3000')
})
ユーザーログインのためのフォーム送信を例にとると、通常、この形式はjson
データを渡すために使用されます。Postman または ApiPost を開いてリクエストを送信します。
サーバー プログラムは次のように結果を出力します。
要約する
この記事では、request
オブジェクトの一般的に使用されるいくつかのプロパティを通じて HTTP リクエストを処理する方法を紹介します。
- request.method: リクエストメソッドを取得します。
- request.url: リクエスト URL を取得するには、 などのツールを使用して
url
さらにquerystring
分析する必要があります。 - request.headers: リクエストヘッダ情報の取得
- request.body: リクエスト本文データを取得します。これは、次に従って
Content-Type
さまざまな形式に解析する必要があります。
次の記事では、reponse
完了したリクエストの処理を完了するためのオブジェクトを紹介します。