Node.js, Express, Path で res.sendFile を使ってファイルを送り出す:完全ガイド
Node.js, Express, Path で res.sendFile を使って絶対パスでファイルを送りする方法
しかし、res.sendFile
を使うには、絶対パス または ルートディレクトリ を指定する必要があります。これができていない場合、以下のエラーが発生します。
Error: ENOENT, stat
このエラーを回避するには、以下の2つの方法があります。
絶対パスを使用する
絶対パスとは、コンピュータ内のファイルを 一意に特定 するためのパスです。例えば、/home/user/public/index.html
は絶対パスです。
const express = require('express');
const path = require('path');
const app = express();
app.get('/', (req, res) => {
const filePath = path.join(__dirname, 'public', 'index.html');
res.sendFile(filePath);
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
上記のコードでは、path.join
関数を使って、__dirname
(現在のスクリプトのディレクトリ) と public/index.html
を結合し、絶対パスを取得しています。
ルートディレクトリとは、静的ファイルを格納するディレクトリのことです。res.sendFile
のオプションとして root
を指定することで、ルートディレクトリを指定できます。
const express = require('express');
const path = require('path');
const app = express();
app.get('/', (req, res) => {
const filePath = 'index.html';
res.sendFile(filePath, { root: path.join(__dirname, 'public') });
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
上記のコードでは、root
オプションを使って、public
ディレクトリをルートディレクトリとして指定しています。これで、index.html
という相対パスでファイルを指定できます。
一般的には、絶対パス を使う方が安全 です。なぜなら、ルートディレクトリを変更した場合、res.sendFile
が動作しなくなる可能性があるからです。
Node.js, Express, Path で res.sendFile を使ってファイルを送り出すサンプルコード
絶対パスを使用する
const express = require('express');
const path = require('path');
const app = express();
app.get('/', (req, res) => {
const filePath = path.join(__dirname, 'public', 'index.html');
res.sendFile(filePath);
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
説明:
express
とpath
モジュールをインポートします。app
という Express アプリケーションを作成します。/
パスへの GET リクエストを処理するルートハンドラーを定義します。res.sendFile
メソッドを使って、ファイルを送り出します。- アプリケーションをポート 3000 で起動します。
ルートディレクトリを指定する
const express = require('express');
const path = require('path');
const app = express();
app.get('/', (req, res) => {
const filePath = 'index.html';
res.sendFile(filePath, { root: path.join(__dirname, 'public') });
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
root
オプションを使って、public
ディレクトリをルートディレクトリとして指定します。
補足:
- 上記のコードは、基本的な例です。実際のアプリケーションでは、エラー処理やセキュリティ対策を追加する必要があります。
- ファイルを送信する前に、ファイルが存在するかどうかを確認する必要があります。
- 大容量のファイルを送り出す場合は、ストリーミングを使用する必要があります。
Node.js, Express でファイルを送り出すその他の方法
send
メソッドは、レスポンスにテキスト、HTML、JSON などを送信するために使用できます。ファイルを送り出す場合、ファイルの内容を文字列に変換してから send
メソッドで送信できます。
const express = require('express');
const fs = require('fs');
const app = express();
app.get('/', (req, res) => {
const filePath = path.join(__dirname, 'public', 'index.html');
const fileContent = fs.readFileSync(filePath, 'utf8');
res.send(fileContent);
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
fs.readFileSync
関数を使って、ファイルを同期的に読み込み、その内容を文字列に変換します。
sendfile
ミドルウェアは、res.sendFile
と同様の機能を提供します。ただし、sendfile
ミドルウェアは、より高速で効率的であると言われています。
const express = require('express');
const sendfile = require('sendfile');
const app = express();
app.get('/', (req, res) => {
const filePath = path.join(__dirname, 'public', 'index.html');
sendfile(req, filePath, { root: __dirname }, (err) => {
if (err) {
console.error(err);
res.status(500).send('Error sending file');
}
});
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
- エラーハンドラーを定義します。
カスタムミドルウェアを作成して、ファイルを送り出すこともできます。これは、より多くの制御が必要な場合や、独自のロジックを実装したい場合に役立ちます。
const express = require('express');
const fs = require('path');
const app = express();
app.use('/public', (req, res, next) => {
const filePath = path.join(__dirname, 'public', req.path);
fs.readFile(filePath, (err, data) => {
if (err) {
if (err.code === 'ENOENT') {
return res.status(404).send('File not found');
} else {
return res.status(500).send('Error reading file');
}
}
res.send(data);
});
});
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
/public
パスへのすべてのリクエストを処理するカスタム
node.js express path