アンケートご協力のお願いgihyo.jpでは,2010年度に向けて豪華プレゼントが当たる読者属性アンケートを実施しております。ご協力ください。

gihyo.jp » DEVELOPER STAGE » 連載 » BK通信 ―Bad Knowhow Tsushin― » #04 ブラウザのバッドノウハウ <form>編

BK通信 ―Bad Knowhow Tsushin―

#04 ブラウザのバッドノウハウ <form>編

ソフトウェアなどを使いこなすために,ストレスを感じながらもしぶしぶ覚えなければならないようなノウハウ,「バッドノウハウ」がテーマの本連載,第4回の今回はブラウザのBKを,<form>タグに関連するものに絞って取り上げたいと思います。

URLの+と%20の関係

HTMLの<form>タグを使うと,ブラウザからサーバにデータを送ることができます。<form>にmethod="GET"という属性が指定されている場合,ブラウザは,以下のように,キーと値のペアをURLの末尾に付加してサーバにリクエストを送ります。

  • http://example.com/webdb.cgi?key1=value1&key2=value2

これらのペアを「クエリ」と呼びます。このときキー,あるいは値に=などの予約記号が含まれている場合,%3Dのように%+16進数でエンコードします(注1)。

ところが,これには例外がありASCIIの空白は「+」に変換されます。しかし,URI(注2)を定義している仕様を見てもクエリ内の空白は+に変換せよとは書かれていません注3。では,どこから+がやってくるのかというとHTMLの規格の中で,フォームデータのエンコード形式であるapplication/x-www-form-urlencodedでは「空白は+で置き換えられる」と明記されています(注4)。つまり,空白を+に置き換えるという仕様は,URLのクエリ部分にだけ適用されます。

よって,空白を含むファイル名"foo bar.html"に対するURLのつもりで,リスト1①のようにすると,foo+bar.htmlというファイル名として解釈されてしまいます。空白を%20でエンコードするのが正解です(リスト1②)。

%20と+を使い分けるのはややこしいので,個人的には常に%20を使えばいいような気がします。

リスト1 空白は%20でエンコード

①http://example.com/foo+bar.html
②http://example.com/foo%20bar.html

注1)
これを「パーセントエンコード」と呼びます。RFC3986の2.1「Percent-Encoding」を参照。
URL:http://www.ietf.org/rfc/rfc3986.txt
注2)
Uniform Resource Identierの略。URLはURIの一種。
注3)
注1と同じRFC3986の3.4「Query」を参照。
注4)
以下の17.13.4「Form content types」を参照。
URL:http://www.w3.org/TR/html401/interact/forms.html

<form>のaccept-charsetパラメータ

ブラウザからサーバにデータを送る場合に問題になるのが,テキストデータに使われる文字エンコーディングです。通常,ブラウザはページで使われているのと同じエンコーディングでテキストデータをサーバに送信します。あるいはaccept-charsetという属性を<form>に指定すれば,ページと異なるエンコーディングで送信することもできます。しかし,Internet Explorer 7(以下,IE7)はaccept-charsetを無視します(注5)。

実験は簡単です。リスト2のようなファイルをShift_JISで保存してIE7に読み込ませます。表示されるフォームに「あいう」と入力してcキーを押すと,図1のような画面が表示されます。

リスト2 test.html

<meta http-equiv="content-type"
      content="text/html; charset=Shift_JIS">
<form method="GET" accept-charset="UTF-8">
<input type="text" name="foo">
</form>

図1 Shift_JISでエンコードされた

図1 Shift_JISでエンコードされた

URLの末尾に「?foo=%82%A0%82%A2%82%A4」が付加されました。これは「あいう」がShift_JISでエンコードされていることを意味します。accept-charsetに指定したUTF-8は無視されました。

IE7に限らず,他のプログラムもaccept-charsetを守ってくれるとは限りませんから,あくまでもaccept-charsetはおまじない程度に考えるのがよさそうです。

注5)
IE7.0.5730.13で動作検証しました。IE6でもおそらく同様ですが,手元に動作検証できる環境がないため,今回はIE7に絞って話を進めます。

<form>の_charset_パラメータ

フォームから送られてきたテキストデータを正しく扱うには,どのエンコーディングが使われているかサーバ側のプログラムで把握する必要があります。一番簡単なのは,すべてのページをUTF-8にして,フォームからはすべてUTF-8でデータを受け取るとると決める方法です。しかし,場合によっては,歴史的な理由により,ページによってマチマチなエンコーディングが使われているかもしれません(古いページはすべてShift_JISなど)。こんなときこそaccept-charsetが役立つはずなのですが,前述のとおりIEはこれを無視します。万事休す...と思いきや,ここでバッドノウハウの登場です。

リスト3のように,フォームに_charset_というパラメータをhiddenで追加します。そして,先ほどと同様にIEからアクセスして「あいう」を入力してみると...(図2)。

リスト3 _charset_パラメータをセット

<meta http-equiv="content-type"
      content="text/html; charset=Shift_JIS">
<form method="GET" accept-charset="UTF-8">
<input type="text" name="foo">
<input type="hidden" name="_charset_"> //この1 行を追加
</form>

図2 _charset_=shift_jis が追加された

図2 _charset

なんと,URLに_charset_=shift_jisというエンコーディング名が入りました。サーバ側のプログラムは,この値からテキストデータのエンコーディングを特定できます。ただし,悪意のあるユーザが意図的に間違った_charset_をサーバに送ってくる恐れがあるので,_charset_を完全に信用すると文字化けなどの原因になります。厳密に処理するには,入力データが_charset_で指定されたエンコーディングのテキストとして正しいバイト列か検査するとよいでしょう。

実は,この_charset_の仕様は2002年の時点でMozillaに移植されていて,Firefoxからも利用できます。Mozillaでは一時期,フォームにPOSTするときのHTTPリクエストのContent-Typeヘッダにcharsetを追加することを検討したようですが,charsetパラメータを付加すると問題が起きるサーバプログラムがあまりに多かったため,結局中止したようです。

他のやり方としては,リスト4のように隠しテキストを入れておいて,このテキストがどのようにエンコードされたかによってエンコーディングを判別するという方法もあります。

リスト4 隠しテキスト

<input type="hidden" name="test" value=" あ">

まとめ

今回は,<form>タグに関連するブラウザのバッドノウハウを3つ紹介しました。とりわけ,_charset_はバッド度の高いBKだと思います。次回は,その他のブラウザのBKを紹介する予定です。

著者プロフィール

高林哲(たかばやしさとる)

ソフトウェアエンジニア。バッドノウハウの研究,スルー力の探究,自転車置場の建設,Binary 2.0の布教などの活動を行っている。共著に『Binary Hacks』(オライリー 2006年)。ブログはhttp://0xcc.net/

著書

  • Binary Hacks ハッカー秘伝のテクニック100選

    Binary Hacks ハッカー秘伝のテクニック100選(オライリー・ジャパン)

コメント

コメントの記入

パスサポ

多数の情報処理技術者試験対策書籍の発行実績を誇る技術評論社がお届けする,資格試験合格サイト「めざせ! 情報処理試験 パスサポ」が開設されました。

ピックアップ

サクセスストーリーに続く,快適サーバー運用管理のヒント!

データの増大,煩雑な管理,システムダウン,セキュリティなど,迫りくる課題からシステム管理者の負担を軽くするポイントを解説します。

gihyo.jp インフラエンジニア情報局

ネットワークやITにかかわるあらゆる業種で必要とされるインフラエンジニアに向けた技術情報や心構え,その魅力について多角的に紹介。

テストエンジニア ステーション

いま,ITに関わるあらゆる開発業務で注目されつつあるテスト系エンジニアをターゲットにしたコンテンツサイトを展開します。

一行クイックアンケート

gihyo.jpで取り上げてほしいネタは?

※検索はページ右上の検索ボックスをご利用ください。

その他の連載

読むウェブ ~本とインタラクション

ディスプレイで読む活字とそのインタラクション(interaction:相互作用)について,最新Webを紹介しながら読み解いていく。

いま,見ておきたいウェブサイト

この連載では,国内外の最新のウェブサイトを隔週更新で取り上げ,これら最新サイトの特徴や素晴らしい部分を,さまざまな角度から解説していきます。

Windows phoneアプリケーション開発入門

Windows Marcketplace for Mobileがサービス開始され,作成したアプリケーションを個人でも世界をターゲットに公開できる環境が整ってきました。これを機にWindows phoneアプリケーションの開発をしてみませんか?

ここは知っておくべき!Windows Server 2008技術TIPS

5年ぶりのサーバOSとなったWindows Server 2008が出荷されて早2年。2009年にはR2が出荷され,再び注目を集めています。発売前から実施したトレーニングによって感じた,インフラエンジニアの方々に知っておいていただきたい機能を中心にご紹介します。

キーパーソンが見るWeb業界

本連載はWeb Site Expert/gihyo.jpとの連動企画です。阿部淳也, 長谷川敦士, 森田雄のお三方による,Web業界をテーマにした座談会です。

きたみりゅうじの聞かせて珍プレー

ソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。みなさんからの投稿もお待ちしてます!

ActionScript 3.0で始めるオブジェクト指向スクリプティング

野中文雄氏が,簡単なスクリプトは書いたことがあるという初級者を対象に,ActionScript 3.0の基本からクラス定義までを解説します。

まだ間に合う「ITパスポート」受験対策 原山先生の短期合格塾

この連載では,4月18日のITパスポート試験の受験に向けて,短い期間で効率良く受験対策を行う方法や,確実に得点するための裏ワザなどを伝授していきます。

連載一覧

gihyo.jp

  • DEVELOPER STAGE
  • ADMINISTRATOR STAGE
  • WEB+DESIGN STAGE
  • LIFESTYLE STAGE
  • SCIENCE STAGE
  • NEWS & REPORT

書籍案内

  • 新刊書籍
  • 書籍ジャンル一覧
  • 書籍シリーズ一覧
  • 新刊ピックアップ
  • ロングセラー
  • 電脳会議

定期刊行物一覧

  • Software Design
  • WEB+DB PRESS
  • Web Site Expert
  • 組込みプレス