UTF-8対応Webアプリケーションの構築の記事の第1回は、Active Server Pages(ASP)を取り上げたいと思います。WebブラウザからのHTTPリクエストをIISが受け取り、ASPに受け渡し、スクリプトが逐次実行されて、その結果がHTTPレスポンスとして返る、という仕組みについては皆さんご存知の通りです。通常、日本国内で利用されるASPベースのアプリケーションについては文字コードについてシビアに考えなくても、WebサーバもWebブラウザも日本語環境で、バックエンドのデータベースも日本語というのが典型的な作り方だと思います。英語圏においても同様で、Webサーバ、Webブラウザ、バックエンドデータベースは英語環境です。
私が命じられたのは、英語版OSで動くWebサーバ、データベースサーバを使って構築されているWebアプリケーションを、マルチバイトをサポートするものに作り変えることでした。日本語版OS、日本語版データベースは使えません。「さて、どうしよう」しかも期限は3週間以内(営業日で15日間!)、担当は私一人。改良する製品の前提知識もないまま、Visual SourceSafeへのアクセス権が与えられ、ソースコードが開示されました。ASPのページ数は170枚、ActiveX DLL関係のプロジェクトは25個、SQLのテーブルは59個、ストアドプロシージャは244個・・・。まったく初見の状態。「そんな無茶なーーーー!!!」と思いながらも引くに引けない業務命令。まずは全体のアーキテクチャを図示し、どこをどう変えればよいのかという仮説を立てるところからはじめました。
最初に考えた戦略は、すべてUnicodeにすることでした。データベースのテーブル内の文字列をすべてUnicodeに、ActiveX DLL内の文字もUnicodeに、そしてASPの入出力はUTF-8に。結果としてそれは間違いではなかったのですが、途中、何度も挫折するはめに。挫折の理由は、文字が化けてしまうことでした。その理由は、VB編で紹介したいと思います。挫折すると仮説が揺らいでしまい、Unicodeを捨ててMBCSに走ろう、という誘惑に駆られます。何度もMBCSに走ろうと考えました。しかし、MBCSに走ってしまうと、コードページの違いと戦うことになるわけです。簡体字中国語、繁体字中国語、韓国語、これらのサポートが必須だったため、MBCSに走ると、日本を含め、4種類のコードページを扱わなければなりません。そうなると、アプリケーションを構成している要素をコードページごとに分けて考える必要があります。3週間でそんなことをやっている余裕はありません。「UTF-8を信じてみよう」それしかありませんでした。
・・・
ASPをUTF-8化するためには、2つのポイントがあります。
1:コードページの明示
<%@ Language="VBScript" CodePage=65001 %><%@ Language="VBScript" CodePage=65001 %><%@ Language="VBScript" CodePage=65001 %>
<%@ Language="VBScript" CodePage=65001 %>
2:<HEAD>タグの<META> での文字コードの明示
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
このポイントについては、MSDNなどで調べればすぐにわかります。ここまでは簡単な話です。次の問いに簡単に答えられる人は、それほど多くないのではないでしょうか。
問題:
Webブラウザから送信されたUTF-8文字列をASPが受け取ったとします。Request.Form()メソッドで返される文字列の文字コードは何になるでしょうか。ただし、IISが稼動しているOSは、英語版のWindows 2000 Serverとします。
読者をじらしても意味がありませんので、解答をお教えします。答えは、WindowsのUnicodeであるUCS-2の文字列です。うれしいことにUTF-8からUCS-2への変換は、ASP上で自動的に行われます。私の場合は、これに気が付かずにかなり遠回りをしてしまいました。(営業日で9日くらい使ってしまった・・・:実際は別の調査も難航していたのが原因なのですが・・・)
さて、どうやってこの自動変換に気が付いたかを紹介します。次のようなコードをASPに配置して、HTMLフォームからUTF-8文字列を送信してみたのです。
[文字のバイト数:] <%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %><%= LenB(Request.Form("teststring") %>
1文字の漢字「あ」をUTF-8として送信して、[文字のバイト数:]の結果が3になればUTF-8のままです。実際に実行してみると、結果は3ではなく2でした。
「ん?これってUCS-2」、この事実はかなり私を勇気付けてくれました。ASPの中の文字列がWindowsのUnicodeであるならば、ActiveX DLLに受け渡す直前での文字コード変換が不要ということです。つまり、ASP側は上述の1と2さえクリアしていれば、WebブラウザとWebサーバ間でのUTF-8での入出力は問題なく実行できるというわけです。
次回は、データベース側の話を書きたいと思います。