文字コード変換 JavaScript の説明
戻る


このプログラムは,テキスト データの文字コードの変換を行うものです.JavaScript の文字列とファイルのテキスト データとの間で文字コードの変換を行います.
JavaScript の文字列の内部コードは UTF-16 です.外部(ネットワークやファイルなど)のテキスト データを JavaScript で扱うためには,それらで使われている文字コードと内部コードを変換する必要があります.
外部のデータのコードから内部コードへの変換は FileReader を使えばできます.TextDecoder が実装されていれば TextDecoder を使って変換することもできます.
内部コードから外部のデータのコードへの変換については,UTF-8 への変換だけは,TextEncoder が実装されていれば TextEncoder を使ってできます.その他の文字コードへの変換を直接行うような機能は多分(今のところ)JavaScript には無いと思います.
自前で変換処理を用意する場合,他の Unicode(UTF-8 など)との変換は単純な規則で可能ですが,それ以外の文字コードとの間で変換を行うには,一般的には変換テーブルが必要になります.このプログラムでは,変換テーブルを使わずに JavaScript の機能の範囲で(無理やり)変換を行います.

このプログラムは,次の二つの処理を行います.
  • テキスト ファイルを読み込んで文字コードを変換し,画面上のテキスト入力エリアに表示します.

  • 画面上のテキスト入力エリアの内容の文字コードを変換し,ファイルに書き出します.

使い方

● ファイルからの読み込み

「入力文字コード」に,変換したい文字コード(ISO-2022-JP,UTF-8 など)を入力します.使用しているブラウザが対応している文字コードであれば,何でも指定できます.
「入力文字コード」の右側の「選択」ボタンを押すと,よく使われる文字コードを一覧から選ぶことができます.一覧に無い文字コードでも,直接キー入力すれば入力できます.
「読み込み」ボタンを押してファイルを選ぶと,ファイルの内容がコード変換されて,画面下方のテキスト入力エリアに表示されます.
ファイル内のテキストの改行コードは LF/CR/CR+LF の何れでも構いません.JavaScript での改行コードに変換されます.

● ファイルへの書き出し

画面下方のテキスト入力エリアに,変換するテキストを入力します.
「出力文字コード」に,変換したい文字コードを入力します.(ファイルからの読み込みの場合と同様)
「改行」で,ファイルに出力する改行コードを選びます.
「書き出し」ボタンを押すと,テキスト入力エリアの内容をコード変換し,ファイル ダウンロードの形でファイルに保存します.


変換の仕組み

UTF-16/UTF-32 との変換については,Unicode の仕様に従って単純に符号化方式を変換しています.
それ以外のコードとの変換については以下のような方法で行っています.

● ファイルのコードから内部コードへの変換

FileReader の readAsText() を使います.
ファイルから取得した File オブジェクトから,readAsText() で文字コードを指定して変換後のテキストを得ます.

● 内部コードからファイルのコードへの変換

フォーム送信時のコード変換機能を使います.
フォームは通常は入力データをサーバーに送信するために使うものですが,サーバー以外の送信先を指定しても「それなり」に動作します.このプログラムでは,フォームの ACTION 属性に "data" URL を指定しています.
送信時に生成される URL のクエリー文字列の部分を使ってコード変換を行います.
フォームの METHOD 属性を GET(デフォルト)にして送信すると,フォーム内の送信対象項目の内容が(URL エンコードされて)送信先 URL にクエリー文字列として付加されます.フォームの ACCEPT-CHARSET 属性に文字コードを指定すると,クエリー文字列は指定した文字コードに変換されたものになります.
フォームの TARGET 属性に作業用のフレームを指定し,変換したいテキストをフォーム内の送信対象項目にして送信します.
フレーム内のドキュメントからそのドキュメントの URL を取得し,クエリー文字列の部分から変換されたテキストのデータを取り出してデコードし,変換後のテキストを得ます.

関連する部分の HTML はこのような感じになります.
<FORM … TARGET="target">
<TEXTAREA NAME="d" … ></TEXTAREA>
</FORM>
<IFRAME NAME="target" … ></IFRAME>
たとえば,文字コードが ISO-2022-JP で,TEXTAREA 項目に“あいう”と入力して送信すると,フレーム内のドキュメントの URL がこのようになります.
{フォームの ACTION 属性に指定したもの}?d=%1B%24B%24%22%24%24%24%26%1B%28B
“?d=”の後ろの部分が,“あいう”が ISO-2022-JP に変換され,URL エンコードされたものです.

このプログラムでは使っていない方法ですが,フォームの ACTION 属性に指定するものが一定の条件を満たしていれば,フレームの contentDocument プロパティでフレーム内のドキュメントを取得して,そこからドキュメントの URL を取得することができます.

最近のブラウザでは,フレームの親ドキュメントとフレームにロードするドキュメントが同一オリジンでないと,contentDocument でドキュメントを取得することはできないようです.
たとえば,フレームの親ドキュメントのファイルと同じディレクトリにあるファイルの URL を ACTION に指定するなどの方法で,contentDocument でドキュメントを取得できます.

ブラウザの種類やバージョンによっては,ACTION 属性に指定するものが "data" URL や Blob の URL,"about:blank" でも,contentDocument でドキュメントを取得できる場合があります.
ただ,そのような ACTION の場合は,ブラウザの種類やバージョンによっては URL にクエリー文字列が付かないこともあるので,その場合はこのプログラムの目的には使えません.

また,最近のブラウザでは,フレームの親ドキュメントがローカル ファイル(URL が“file:/// 〜”)の場合は,ロードするドキュメントもローカル ファイルの場合であっても同一オリジンとしては扱われないようなので,contentDocument でドキュメントを取得することはできません.

そのように,contentDocument でドキュメントを取得する方法には制限があるので,このプログラムでは contentDocument でドキュメントを取得することはせず,フレームにロードしたドキュメント内のプログラムと通信してドキュメントの URL を取得するようにしました.
具体的には,フレームにロードしたドキュメント内の JavaScript で
parent.postMessage(location.href, '*')
としてドキュメントの URL をフレームの親ウィンドウに送信し,親ウィンドウの側では message イベントで URL を受け取ります.
この JavaScript を "data" URL にして ACTION 属性に指定しています.
"data:text/html,"
  + encodeURIComponent("<SCRIPT TYPE='text/javascript'>parent.postMessage(location.href, '*')</SCRIPT>")
少なくとも最近の主要なブラウザでは,"data" URL にはクエリー文字列が付くようです.
このプログラムで使うのはクエリー文字列の部分なので,送信するのは本来は location.search でよいのですが,location.search だと Firefox ではなぜか "data" URL のクエリー文字列を取得できないので,location.search ではなく location.href を使っています.


UTF-16/UTF-32 との変換

Firefox も Opera も,上述の方法では UTF-32 との変換ができません.
UTF-16 との変換(エンディアンのみの変換になる)についても,内部コードから UTF-16 への変換は上述の方法ではできません.UTF-16 から内部コードへの変換はできるようですが,データに signature(BOM)が付いていると,文字コードの指定を無視して signature のエンディアンで変換されてしまいます(signature と異なるエンディアンを指定しても意味はありませんが).
内部コードと他の Unicode との変換は簡単にできるので,上述の方法とは別に UTF-16BE/UTF-16LE/UTF-32BE/UTF-32LE との変換を行っています.


戻る