httpクライアント(POSTリクエスト)とは、Node.jsでサーバーのURLにPOSTリクエストを送る。
ブラウザでサーバーにアクセスする場合はPOSTリクエストをサーバーに送っている。
このPOSTリクエストをNode.jsで行う。
このPOSTリクエストを送信するときにデータをchunk分割してサーバーに送信する。
環境
Windows10(64bit)
nvm(Node Version Manager)を使用する。
nvmはnodeとnpmのバージョンの切り替えができる。
node.jsはアップデートが頻繁に行われるため、バージョン管理ツールを使うと都合が良いことが多い。
「特定のプロジェクトに必要なNode.jsのバージョンを簡単にインストールして使用することができる。」や「プロジェクト毎にNode.jsのバージョンの切り替えが簡単になる。」等のメリットがある。
nvm 1.1.10
node v18.15.0
npm 9.5.0
Node.jsでサーバーのURLにデータをchunk分割してpostリクエストを送るコード「post2.js」を次に示す。
(function() {
// Node.jsのhttpsモジュールをrequireを使ってインポートして、定数httpsに格納する。
const https = require("https");
const {
Readable
} = require('stream');
class ChunkedStream extends Readable {
constructor(data, chunkSize) {
super();
this.data = data;
this.chunkSize = chunkSize;
this.offset = 0;
}
_read() {
const chunk = this.data.slice(this.offset, this.offset + this.chunkSize);
this.offset += this.chunkSize;
this.push(chunk || null);
}
}
const url = "https://localhost";
// リクエストのオプションを設定
const options = {
method: 'POST',
// Node.jsのhttpsモジュールはデフォルトでは厳密なSSL証明書の検証を行うため、自己署名証明書を使用しているサーバーに接続しようとするとエラー「self-signed certificate」が発生する。
// 自己署名証明書を使用している場合、httpsリクエストを送信する際に rejectUnauthorizedオプションをfalseに設定することでエラーを回避することができる。
// ただし、セキュリティ上の理由から自己署名証明書を信頼するかどうかは慎重に検討すること。
rejectUnauthorized: false,
// headersに設定するContent-Typeヘッダーは、HTTPSリクエストやレスポンスのボディに含まれるデータの種類を指定するために使用されるため。
// headersに設定するContent-Lengthヘッダーは、HTTPリクエストまたはレスポンスのボディのサイズをバイト単位で指定する。つまり、ボディの内容の長さを示すために使用する。
// HTTP POSTリクエストでボディをチャンク分割して送信する場合、Content-Lengthヘッダーの設定は必要ない。
// なぜなら、チャンク分割を使用する場合、リクエストボディの全体のサイズが事前にわからないため、正確なコンテンツの長さを指定することができない。
// 代わりに、チャンク分割されたデータを送信する際には、Transfer-Encodingヘッダーを使用してチャンク転送エンコーディングを指定する。
headers: {
'Content-Type': 'text/plain', // リクエストボディのデータ形式に合わせて設定
'Transfer-Encoding': 'chunked',
// Node.jsからpostメソッドで手動送信
'User-Agent': 'Manual submission via post method from Node.js', // ユーザーエージェントを設定
},
};
//リクエストを送信する。
// httpsオブジェクトからrequestメソッドを実行する。
// requestメソッドは、引数としてリクエストを処理するコールバック関数を受け取る。
// レスポンスを処理するためのコールバック関数を指定する。
// コールバック関数は、レスポンスオブジェクト(res)を受け取りレスポンスの処理を行う。
const req = https.request(url, options, (res) => {
console.log(`statusCode: ${res.statusCode}`);// ステータスコードを表示する。
console.log(`content-type: ${res.headers['content-type']}`); // レスポンスのコンテンツタイプを表示する。
// res.pipe(process.stdout)は、レスポンスストリームを標準出力ストリームにパイプ接続する。
// pipeメソッドは、Readableストリームからデータを読み取り、そのデータをWritableストリームに書き込む。
// process.stdoutはNode.jsの標準出力ストリームを表しており、res.pipe(process.stdout) によって、レスポンスのデータが読み取られて標準出力に表示される。
// つまり、HTTPS POSTリクエストを送信し、レスポンスを取得した後、そのレスポンスのデータを標準出力に表示するという動作になる。
// レスポンスオブジェクト(res)は、https.IncomingMessageオブジェクトのインスタンスである。
res.pipe(process.stdout);
let responseData = '';
//data受信イベントの発生時に断片データ(chunk)を取得する。
res.on('data', (chunk) => {
responseData += chunk;
});
//受信完了(end)イベント発生時
//「end」イベントは、レスポンスのデータの読み取りが完了した場合に発生する。
res.on('end', () => {
console.log(responseData);
console.log("レスポンスの読み取りが完了しました");
// ここで必要な後処理を実行
});
});
//リクエストの送信中にエラーが発生した場合に「error」イベントは発生する。
req.on('error', (err) => {
console.error(err.message);
});
//リクエストボディのデータを設定
const requestBody = "PostData";
const chunkSize = 3; // チャンクのサイズを設定
// Readableストリームを作成
// リクエストのボディをチャンク分割して送信する
const stream = new ChunkedStream(requestBody, chunkSize);
stream.on('data', (chunk) => {
req.write(chunk);
});
stream.on('end', () => {
req.end();
});
})();
post2.jsを実行する。Node.jsで立ち上げたサーバー「https://localhost」に「POSTリクエスト」を送信する。
c:\node\https_server>node post2.js
statusCode: 200
content-type: text/plain;charset=utf-8
method:POST
req.url:/
PostData
Hello World! POST
method:POST
req.url:/
PostData
Hello World! POST
レスポンスの読み取りが完了しました
c:\node\https_server>
サーバーが立ち上がっていない場合はエラーになる。
c:\node\https_server>node post2.js
connect ECONNREFUSED ::1:443
c:\node\https_server>