小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


クラシックASPアプリケーションのUTF-8化についてまとめてみた。

クラシックASPで作成したアプリケーションをUTF-8化する際のポイントをまとめてみました。

Webサーバ

Windows 2000 および 2003(もちろん2008も)ServerはUnicodeに対応しているため、Webサーバ側で特別な設定をする必要はありません。

ASP(Active Server Pages)のUTF-8化

クラシックASPアプリケーションをUTF-8にするためには、以下の2つの方法があります。

  • アプリケーションを構成しているファイル単位でエンコーディングを指定する
  • アプリケーション単位でエンコーディングを指定する
ファイル単位でのエンコーディング指定

1.ASPファイルの先頭に以下の記述を追加します。65001という数字は、UTF-8を示しています。

<%@ CODEPAGE=65001 %>
<% Session.CodePage=65001 %>

2.ASPファイルを保存する際に、エンコーディングにUTF-8を指定して、保存します。*1

アプリケーション単位でのエンコーディング指定

アプリケーション単位にエンコーディングを指定する場合は、IISのメタベースプロパティ(ASPCodePage)に65001を指定します。

2009.10.08追記

具体的には、C:\WINDOWS\system32\inetsrvディレクトリ配下にあるMeataBase.xmlというファイルを開き、仮想ディレクトリ名で設定箇所を検索します。そして、仮想ディレクトリのタグ内にASPCodePage="65001"と追記するだけです。これにより、アプリケーション全体の文字コードがUTF-8で統一されます。
メタベースプロパティの設定方法は、IIS(Internet Information Server)のメタベースプロパティを変更する方法 - 大人になったら肺呼吸 はてなブックマーク - IIS(Internet Information Server)のメタベースプロパティを変更する方法 - 大人になったら肺呼吸にも記載していますので、こちらも参照してください。

ASP では、そのページでサポートされる言語を指定するために @CODEPAGE 宣言 (日本語の場合は @CODEPAGE=932) を使用し、アプリケーション全体の言語を指定するためにメタベースの ASPCodePage プロパティを使用します。@CODEPAGE 宣言を使用した場合は、その値を使用して、ASP ページのコンパイル中にすべての文字列リテラルが処理され、実行中に動的データ (たとえば、データベースから取得したデータ) が処理されます。@CODEPAGE 宣言がない場合、データは Windows 2000 の標準言語で記述されているものと見なされます。ASPCodePage プロパティを使用すると、ASP アプリケーションのすべてのページに 1 つの言語を指定するようにプログラミングできます。ASP は、アプリケーションの各ページのコードがその設定に準拠するものと見なします。
Windows 2000 における ASP を使った Web ページの多言語対応化 はてなブックマーク - Windows 2000 における ASP を使った Web ページの多言語対応化

HTMLファイルのUTF-8化

画面のレイアウトなどをテンプレートファイルとしてHTMLファイルに記述している場合は、HTMLファイルもUTF-8にする必要があります。以下のように、headタグ内の文字コード指定をUTF-8に変更します。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

スタイルシートのUTF-8化

スタイルシートをUTF-8で記述する場合には、.cssファイルの先頭に以下の1行を追加します。

@charset = 'utf-8';

データベースのUTF-8対応

データベースは、Microsoft SQL Serverを前提として書きますが、SQLServer 2000および2005、そして2008もUnicodeをサポートしています。

テーブルのカラムにchar、varchar、textを使用している箇所については、nchar、nvarchar、nvarchar(max) などの Unicode データ型への変換を行う必要があるようです。

国際的なデータベースの文字データを管理する最も簡単な方法は、char、varchar、text などの非 Unicode データ型を使用するのではなく、常に nchar、nvarchar、nvarchar(max) などの Unicode データ型を使用することです。それによって、クライアントには、他のすべてのクライアントと同じ文字でデータが表示されます。国際的なデータベースを使用するすべてのアプリケーションで、非 Unicode データ型の変数の代わりに Unicode データ型の変数を使用すれば、システム内で文字の変換を行う必要がなくなります。

注 : ntext データ型は、将来のバージョンの Microsoft SQL Server では削除される予定です。
Microsoft SQL Server 2005 のインターナショナル機能 はてなブックマーク - Microsoft SQL Server 2005 のインターナショナル機能

ファイルの保存形式について

クラシックASPアプリケーションをUTF-8にする場合、すべてのファイル(.aspや.jsや.cssなど)をUTF-8の形式で保存する必要があります。このとき、ファイルの先頭にBOMを付加した場合、IISが正しく動作しないようです。

2009.11.02追記

上記の説明には誤りがありました。正しくは、@codepageに指定したコードページとファイルの保存形式は、合わせる必要があります。上記の例のように、@codepageに65001を指定した場合は、aspファイルをUTF-8形式で保存する必要があります。*2

ASP ファイル ページのエンコード形式は、そのページの @CodePage と同じ設定でなければなりません。
[IIS]CodePage を UTF-8 に設定すると一致しない文字で出力されることがある はてなブックマーク - [IIS]CodePage を UTF-8 に設定すると一致しない文字で出力されることがある

アプリケーションのUTF-8化に際して、必ずしもUTF-8の形式でASPファイルを保存しなければならないということはないようです。@codepageとファイルの保存形式が一致していれば良いため、ファイルの保存形式はShift_JISで、アプリケーションをUTF-8化させることは可能です。具体的には、以下のように@codepageディレクティブで指定したコードページをsession.codepageで上書きします。これにより、Shift_JISで保存したaspファイルでもUTF-8のページを表示することが可能になります。

<%@ CODEPAGE=932 %>
<% Session.CodePage=65001 %>

トラブルシューティング

IEでfont-family指定なしのUTF-8ページを表示した場合のフォント

Internet Exlorer6および7(8は未検証)で、font-family指定なしのUTF-8ページを表示した場合、英字フォントがTimes New Romanになります。以前のアプリケーションとフォントが変わってしまう場合には、スタイルシートにfont-familyを指定する必要があります。

たまたま「font-familyを指定しない」、つまり各ブラウザのデフォルトフォントで表示させたいhtmlコンテンツがありまして、それをUTF-8にしたところ、IE6では1バイト文字フォントがTimes New Romanになってしまう問題に遭遇しました。
いずみのぶろぐ : IE6 on utf-8 でのフォント問題を回避する はてなブックマーク - いずみのぶろぐ : IE6 on utf-8 でのフォント問題を回避する

SQLServerにJIS2004の文字を格納すると??で文字化けする

SQL Server で Unicode 文字列定数を扱う場合には、Unicode 文字列の前に大文字の N が必ず必要です。このため、以下のようにパラメタの前にNプレフィックスを付加します。

INSERT INTO TABLE ("ID", "NAME") VALUES ('1', N'森鴎外');

SELECT * FROM TABLE WHERE name = N'森鴎外' 
2009.10.03追記
UTF-8形式でクライアントに出力したCSVファイルをExcelで開くと文字化けする

アプリケーションが出力した情報をCSVファイルとしてクライアントにダウンロードさせる機能があった場合、UTF-8の形式で出力した場合、そのCSVファイルはExcelでは開くことができません。これは、Excelの仕様に基づく制限事項です。

*1:コードページとファイルの保存形式が一致しない場合、正しく動作しない可能性があります。

*2:UTF-8ファイルの先頭にBOMを付加した場合、IISが正しく動作しないようです。[IIS] UTF-8 でエンコードされたファイルの BOM がデータとして扱われる