markdown
はじめに (対象読者・この記事でわかること)
このページは、Webフロントエンド開発に携わる初心者から中級者を対象に書かれています。HTML に配置した .txt や .md といったテキストファイルを、ブラウザ上の JavaScript だけで取得し、ページ内に表示したり加工したりしたいと考えている方に最適です。
この記事を読むと、以下のことがすぐに実践できるようになります。
- HTML にテキストファイルへのパスを書くだけで、JavaScript から 非同期に取得できる仕組みを理解できる
fetchAPI とResponse.text()の基本的な使い方とエラーハンドリング方法が分かる- 取得したテキストを DOM に挿入したり、正規表現で加工したり、文字コードの変換を行うテクニックが身につく
背景として、ローカルのサーバーや CDN に置いたテキストデータをクライアント側だけで扱いたいケースが増えている点があります。サーバーサイドに手を加えず、純粋なフロントエンドだけで完結できる手法は、プロトタイピングや小規模なツール作成で特に有用です。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- HTML/CSS の基本 – 要素の構造や属性の書き方が分かっていること
- JavaScript の基礎 – 変数宣言、関数、非同期処理(Promise)の概念が理解できていること
テキストファイル取得の背景と概要
Web ページ上でテキストデータを外部ファイルとして分離して管理する理由は主に 可搬性と保守性 にあります。例えば、利用規約やヘルプ文章、製品マニュアルなどは頻繁に更新されることが多く、HTML に直接埋め込むと変更のたびにページ全体を再デプロイしなければなりません。テキストファイルとして別に置いておけば、サーバー側でファイルだけ差し替えるだけで最新情報を反映できます。
JavaScript でテキストファイルを取得する主な手段は以下の 3 つです。
| 手段 | 主な利用シーン | 特徴 |
|---|---|---|
<script src="..."> |
外部スクリプト | JavaScript ファイル専用、テキスト取得には不向き |
<iframe src="..."> |
別ページ埋め込み | サンドボックス化されるが、取得が難しい |
| Fetch API | 任意のテキスト/JSON/XML | モダンブラウザ標準、Promise ベースで柔軟に扱える |
本稿では、この中でも最もシンプルで汎用性の高い Fetch API を中心に解説します。Fetch は CORS(Cross-Origin Resource Sharing)の制約を受けますが、同一オリジン(同じドメイン・ポート)であれば追加設定なしに利用できます。さらに、Response.text() を呼び出すだけで UTF-8 エンコードされたテキストをそのまま文字列として取得でき、取得後の文字列操作は普通の JavaScript と同様に行えます。
テキストファイル取得と活用:具体的な手順と実装
以下では、実際に HTML にテキストファイルのパスを書き込み、JavaScript で取得・表示・加工する流れをステップごとに示します。開発環境は特別なものは不要で、ローカルの静的サーバー(例: npm start、python -m http.server)さえあれば動作確認できます。
ステップ1:HTML 側にファイルパスを記述
まずは取得対象となるテキストファイル(例: data/info.txt)をプロジェクトの公開ディレクトリに配置します。HTML 側では特にスクリプトを書き込む必要はなく、データ属性や カスタム属性 を利用してパスを埋め込むと、後から JavaScript が参照しやすくなります。
Html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>テキスト取得デモ</title> <style> #output { white-space: pre-wrap; font-family: monospace; margin-top: 1rem; } </style> </head> <body> <h1>テキスト取得デモ</h1> <!-- データ属性に取得したいテキストファイルのパスを保持 --> <button id="loadBtn" data-file-path="data/info.txt">テキストを取得</button> <!-- 取得したテキストを表示する領域 --> <div id="output"></div> <script src="js/main.js"></script> </body> </html>
ポイントは data-file-path 属性です。HTML を編集するだけで取得したいファイルを差し替えられるため、スクリプトの可読性が向上します。
ステップ2:Fetch API でテキストを取得
次に js/main.js を作成し、ボタンがクリックされたときに fetch を呼び出すロジックを書きます。
Js// js/main.js document.addEventListener('DOMContentLoaded', () => { const btn = document.getElementById('loadBtn'); const output = document.getElementById('output'); btn.addEventListener('click', async () => { const filePath = btn.dataset.filePath; // data-file-path の値を取得 try { const response = await fetch(filePath, { method: 'GET', // 同一オリジンなら不要だが、CORS が必要な場合は以下を有効に // mode: 'cors', // credentials: 'same-origin' }); // HTTP ステータスが 200 系でなければエラーにする if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // 文字列として取得 const text = await response.text(); // 取得したテキストをそのまま表示 output.textContent = text; } catch (err) { console.error('テキスト取得エラー:', err); output.textContent = `エラーが発生しました: ${err.message}`; } }); });
解説
await fetch(filePath)で非同期に取得。fetchは Promise を返すのでawaitで結果を待ちます。response.okはステータスコードが 200〜299 のときtrueになるので、失敗時は例外を投げてcatchに渡します。response.text()がテキスト全体を UTF-8 とみなして文字列に変換します。バイナリデータが必要な場合はarrayBuffer()やblob()を用います。- エラーハンドリングは
try…catchでまとめ、UI に分かりやすく表示しています。
ステップ3:取得テキストの加工例
取得した文字列は普通の文字列オブジェクトなので、正規表現や 文字列操作メソッド を自由に使えます。以下は、行頭に行番号を付与し、特定のキーワードをハイライトする例です。
Js// 取得したテキストを加工して表示する関数 function formatText(raw) { const lines = raw.split('\n'); const formatted = lines.map((line, idx) => { // 行番号を付与 let numbered = `${idx + 1}: ${line}`; // キーワード "重要" を赤字に変換 numbered = numbered.replace(/重要/g, '<span style="color:red;">重要</span>'); return numbered; }).join('\n'); // innerHTML で HTML を解釈させる return formatted; } // ボタンのクリックハンドラ内で呼び出す const processed = formatText(text); output.innerHTML = processed; // 注意: XSS 対策が必要ならサニタイズ
ポイント
split('\n')で行単位に分解し、mapで各行に番号付与。replaceで正規表現置換し、HTML タグで装飾。innerHTMLに設定するとタグが解釈され、ハイライトが反映されます。ただし 外部から取得したテキスト に対しては XSS のリスクがあるため、サニタイズライブラリ(例: DOMPurify)で安全化することが推奨されます。
ステップ4:文字コードが UTF-8 でない場合の対処
稀にサーバー側で UTF-8 以外(Shift_JIS、EUC-JP 等)でテキストが保存されているケースがあります。そのまま response.text() を呼び出すと文字化けするので、TextDecoder を使ってデコードします。
Jsasync function fetchWithEncoding(url, encoding = 'utf-8') { const resp = await fetch(url); if (!resp.ok) throw new Error(`HTTP error! ${resp.status}`); const buffer = await resp.arrayBuffer(); // バイナリ取得 const decoder = new TextDecoder(encoding); return decoder.decode(buffer); } // 使用例(Shift_JIS の場合) const raw = await fetchWithEncoding('data/jp.txt', 'shift_jis'); output.textContent = raw;
TextDecoder はブラウザ標準 API で、エンコーディング名は IANA で定義されたものを指定します。これにより、任意の文字コードのテキストでも正しく取得・表示できます。
ハマった点やエラー解決
| 発生した問題 | 原因 | 解決策 |
|---|---|---|
fetch が CORS エラーを返した |
ファイルが別ドメインまたは file:// で実行されていた |
開発は必ず ローカルサーバー(http://localhost)上で行う。外部サーバーの場合はサーバー側で Access-Control-Allow-Origin ヘッダを設定。 |
| 取得したテキストが文字化けした | ファイルが UTF-8 で保存されていなかった | TextDecoder を利用し、実際の文字コード(Shift_JIS 等)でデコード。 |
innerHTML が XSS 警告を出した |
外部テキストにスクリプトタグが混入していた | DOMPurify 等でサニタイズし、innerHTML に渡す前にクリーンアップ。 |
response.ok が false で例外が投げられた |
ファイルパスが間違っていた(404) | コンソールのネットワークタブでリクエスト URL を確認し、正しい相対パスを指定。 |
ベストプラクティスまとめ
- 同一オリジンでテスト → CORS の頭痛を回避。
awaitとtry…catchで非同期エラーハンドリング → UI がフリーズしない。- 文字コードは常に UTF-8 に統一(不可能なら
TextDecoder) → 文字化け防止。 - サニタイズは必須 → セキュリティリスクを低減。
まとめ
本記事では、HTML に埋め込んだテキストファイルを JavaScript の Fetch API で取得し、画面に表示・加工する一連の手順を解説しました。
- データ属性でファイルパスを管理し、HTML とロジックを分離
- Fetch + async/await でシンプルに非同期取得、ステータスチェックとエラーハンドリングを実装
- 取得テキストの加工例(行番号付与・キーワードハイライト)と 文字コード変換(TextDecoder)を紹介
- 実装中に遭遇しやすいエラー(CORS、文字化け、XSS)とその対策を提示
これらを身につけることで、サーバーサイドに手を加えずにフロントエンドだけでテキストデータを動的に扱えるようになります。次のステップとして、取得したテキストを Markdown パーサーで HTML に変換したり、ローカルストレージにキャッシュしたりすると、より高度な UI/UX が実現できます。
参考資料